pax_global_header00006660000000000000000000000064150157663710014525gustar00rootroot0000000000000052 comment=52dacb84f31d55f1d4f0916d48707456a7c90ecb goccy-go-yaml-52dacb8/000077500000000000000000000000001501576637100146665ustar00rootroot00000000000000goccy-go-yaml-52dacb8/.codecov.yml000066400000000000000000000006341501576637100171140ustar00rootroot00000000000000codecov: require_ci_to_pass: yes coverage: precision: 2 round: down range: "70...100" status: project: default: target: 75% threshold: 2% patch: off changes: no parsers: gcov: branch_detection: conditional: yes loop: yes method: no macro: no comment: layout: "header,diff" behavior: default require_changes: no ignore: - ast goccy-go-yaml-52dacb8/.github/000077500000000000000000000000001501576637100162265ustar00rootroot00000000000000goccy-go-yaml-52dacb8/.github/FUNDING.yml000066400000000000000000000000201501576637100200330ustar00rootroot00000000000000github: [goccy] goccy-go-yaml-52dacb8/.github/ISSUE_TEMPLATE/000077500000000000000000000000001501576637100204115ustar00rootroot00000000000000goccy-go-yaml-52dacb8/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000012121501576637100230770ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: bug assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Please provide a minimum yaml content that can be reproduced. We are more than happy to use [Go Playground](https://go.dev/play) **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Version Variables** - Go version: [e.g. 1.21 ] - go-yaml's Version: [e.g. v1.11.1 ] **Additional context** Add any other context about the problem here. goccy-go-yaml-52dacb8/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000011401501576637100241320ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project title: '' labels: feature request assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context or screenshots about the feature request here. goccy-go-yaml-52dacb8/.github/pull_request_template.md000066400000000000000000000002611501576637100231660ustar00rootroot00000000000000Before submitting your PR, please confirm the following. - [ ] Describe the purpose for which you created this PR. - [ ] Create test code that corresponds to the modificationgoccy-go-yaml-52dacb8/.github/workflows/000077500000000000000000000000001501576637100202635ustar00rootroot00000000000000goccy-go-yaml-52dacb8/.github/workflows/go.yml000066400000000000000000000054351501576637100214220ustar00rootroot00000000000000name: Go on: push: branches: - master pull_request: jobs: lint: name: lint runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4 - name: setup Go uses: actions/setup-go@v4 with: go-version: "1.24" - name: run linters run: | make lint race-test: name: Test with -race strategy: matrix: os: [ "ubuntu-latest", "macos-latest", "windows-latest" ] go-version: [ "1.21", "1.22", "1.23", "1.24" ] runs-on: ${{ matrix.os }} steps: - name: checkout uses: actions/checkout@v4 - name: setup Go ${{ matrix.go-version }} uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} - name: test run: | make test i386-test: name: Test in i386 strategy: matrix: os: [ "ubuntu-latest", "windows-latest" ] go-version: [ "1.21", "1.22", "1.23", "1.24" ] runs-on: ${{ matrix.os }} env: GOARCH: "386" steps: - name: checkout uses: actions/checkout@v4 - name: setup Go ${{ matrix.go-version }} uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} - name: test run: | make simple-test fuzz: name: Fuzzing Test runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4 - name: setup Go uses: actions/setup-go@v4 with: go-version: "1.24" - name: run run: | make fuzz ycat: name: ycat runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4 - name: setup Go uses: actions/setup-go@v4 with: go-version: "1.24" - name: build run: | make ycat/build - name: run run: | ./bin/ycat .github/workflows/go.yml page: name: page runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4 - name: setup Node uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' cache-dependency-path: docs/playground/package-lock.json - name: install dependencies run: make -C ./docs/playground deps - name: build run: make -C ./docs/playground build coverage: name: Coverage runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4 - name: setup Go uses: actions/setup-go@v4 with: go-version: "1.24" - name: measure coverage run: | make cover - uses: codecov/codecov-action@v4 with: fail_ci_if_error: true verbose: true token: ${{ secrets.CODECOV_TOKEN }} goccy-go-yaml-52dacb8/.github/workflows/pages.yaml000066400000000000000000000016771501576637100222610ustar00rootroot00000000000000name: Deploy static content to Pages on: push: tags: - v* workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: 'pages' cancel-in-progress: true jobs: deploy: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v4 - name: setup Node uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' cache-dependency-path: docs/playground/package-lock.json - name: install dependencies run: make -C ./docs/playground deps - name: build run: make -C ./docs/playground build - name: setup Pages uses: actions/configure-pages@v4 - name: upload artifact uses: actions/upload-pages-artifact@v3 with: path: './docs/playground/dist' - name: deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 goccy-go-yaml-52dacb8/.gitignore000066400000000000000000000000261501576637100166540ustar00rootroot00000000000000bin/ .idea/ cover.out goccy-go-yaml-52dacb8/.golangci.yml000066400000000000000000000021071501576637100172520ustar00rootroot00000000000000version: "2" linters: default: none enable: - errcheck - govet - ineffassign - misspell - perfsprint - staticcheck - unused settings: errcheck: without_tests: true govet: disable: - tests misspell: locale: US perfsprint: int-conversion: false err-error: false errorf: true sprintf1: false strconcat: false staticcheck: checks: - -ST1000 - -ST1005 - all exclusions: generated: lax presets: - comments - common-false-positives - legacy - std-error-handling rules: - linters: - staticcheck path: _test\.go paths: - third_party$ - builtin$ - examples$ formatters: enable: - gci - gofmt settings: gci: sections: - standard - default - prefix(github.com/goccy/go-yaml) - blank - dot gofmt: simplify: true exclusions: generated: lax paths: - third_party$ - builtin$ - examples$ goccy-go-yaml-52dacb8/CHANGELOG.md000066400000000000000000000122211501576637100164750ustar00rootroot00000000000000# 1.11.2 - 2023-09-15 ### Fix bugs - Fix quoted comments ( #370 ) - Fix handle of space at start or last ( #376 ) - Fix sequence with comment ( #390 ) # 1.11.1 - 2023-09-14 ### Fix bugs - Handle `\r` in a double-quoted string the same as `\n` ( #372 ) - Replace loop with n.Values = append(n.Values, target.Values...) ( #380 ) - Skip encoding an inline field if it is null ( #386 ) - Fix comment parsing with null value ( #388 ) # 1.11.0 - 2023-04-03 ### Features - Supports dynamically switch encode and decode processing for a given type # 1.10.1 - 2023-03-28 ### Features - Quote YAML 1.1 bools at encoding time for compatibility with other legacy parsers - Add support of 32-bit architecture ### Fix bugs - Don't trim all space characters in block style sequence - Support strings starting with `@` # 1.10.0 - 2023-03-01 ### Fix bugs Reversible conversion of comments was not working in various cases, which has been corrected. **Breaking Change** exists in the comment map interface. However, if you are dealing with CommentMap directly, there is no problem. # 1.9.8 - 2022-12-19 ### Fix feature - Append new line at the end of file ( #329 ) ### Fix bugs - Fix custom marshaler ( #333, #334 ) - Fix behavior when struct fields conflicted( #335 ) - Fix position calculation for literal, folded and raw folded strings ( #330 ) # 1.9.7 - 2022-12-03 ### Fix bugs - Fix handling of quoted map key ( #328 ) - Fix resusing process of scanning context ( #322 ) ## v1.9.6 - 2022-10-26 ### New Features - Introduce MapKeyNode interface to limit node types for map key ( #312 ) ### Fix bugs - Quote strings with special characters in flow mode ( #270 ) - typeError implements PrettyPrinter interface ( #280 ) - Fix incorrect const type ( #284 ) - Fix large literals type inference on 32 bits ( #293 ) - Fix UTF-8 characters ( #294 ) - Fix decoding of unknown aliases ( #317 ) - Fix stream encoder for insert a separator between each encoded document ( #318 ) ### Update - Update golang.org/x/sys ( #289 ) - Update Go version in CI ( #295 ) - Add test cases for missing keys to struct literals ( #300 ) ## v1.9.5 - 2022-01-12 ### New Features * Add UseSingleQuote option ( #265 ) ### Fix bugs * Preserve defaults while decoding nested structs ( #260 ) * Fix minor typo in decodeInit error ( #264 ) * Handle empty sequence entries ( #275 ) * Fix encoding of sequence with multiline string ( #276 ) * Fix encoding of BytesMarshaler type ( #277 ) * Fix indentState logic for multi-line value ( #278 ) ## v1.9.4 - 2021-10-12 ### Fix bugs * Keep prev/next reference between tokens containing comments when filtering comment tokens ( #257 ) * Supports escaping reserved keywords in PathBuilder ( #258 ) ## v1.9.3 - 2021-09-07 ### New Features * Support encoding and decoding `time.Duration` fields ( #246 ) * Allow reserved characters for key name in YAMLPath ( #251 ) * Support getting YAMLPath from ast.Node ( #252 ) * Support CommentToMap option ( #253 ) ### Fix bugs * Fix encoding nested sequences with `yaml.IndentSequence` ( #241 ) * Fix error reporting on inline structs in strict mode ( #244, #245 ) * Fix encoding of large floats ( #247 ) ### Improve workflow * Migrate CI from CircleCI to GitHub Action ( #249 ) * Add workflow for ycat ( #250 ) ## v1.9.2 - 2021-07-26 ### Support WithComment option ( #238 ) `yaml.WithComment` is a option for encoding with comment. The position where you want to add a comment is represented by YAMLPath, and it is the key of `yaml.CommentMap`. Also, you can select `Head` comment or `Line` comment as the comment type. ## v1.9.1 - 2021-07-20 ### Fix DecodeFromNode ( #237 ) - Fix YAML handling where anchor exists ## v1.9.0 - 2021-07-19 ### New features - Support encoding of comment node ( #233 ) - Support `yaml.NodeToValue(ast.Node, interface{}, ...DecodeOption) error` ( #236 ) - Can convert a AST node to a value directly ### Fix decoder for comment - Fix parsing of literal with comment ( #234 ) ### Rename API ( #235 ) - Rename `MarshalWithContext` to `MarshalContext` - Rename `UnmarshalWithContext` to `UnmarshalContext` ## v1.8.10 - 2021-07-02 ### Fixed bugs - Fix searching anchor by alias name ( #212 ) - Fixing Issue 186, scanner should account for newline characters when processing multi-line text. Without this source annotations line/column number (for this and all subsequent tokens) is inconsistent with plain text editors. e.g. https://github.com/goccy/go-yaml/issues/186. This addresses the issue specifically for single and double quote text only. ( #210 ) - Add error for unterminated flow mapping node ( #213 ) - Handle missing required field validation ( #221 ) - Nicely format unexpected node type errors ( #229 ) - Support to encode map which has defined type key ( #231 ) ### New features - Support sequence indentation by EncodeOption ( #232 ) ## v1.8.9 - 2021-03-01 ### Fixed bugs - Fix origin buffer for DocumentHeader and DocumentEnd and Directive - Fix origin buffer for anchor value - Fix syntax error about map value - Fix parsing MergeKey ('<<') characters - Fix encoding of float value - Fix incorrect column annotation when single or double quotes are used ### New features - Support to encode/decode of ast.Node directly goccy-go-yaml-52dacb8/LICENSE000066400000000000000000000020601501576637100156710ustar00rootroot00000000000000MIT License Copyright (c) 2019 Masaaki Goshima Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. goccy-go-yaml-52dacb8/Makefile000066400000000000000000000026001501576637100163240ustar00rootroot00000000000000## Location to install dependencies to LOCALBIN ?= $(shell pwd)/bin TESTMOD := testdata/go_test.mod $(LOCALBIN): mkdir -p $(LOCALBIN) .PHONY: test test: go test -v -race ./... go test -v -race ./testdata -modfile=$(TESTMOD) .PHONY: simple-test simple-test: go test -v ./... go test -v ./testdata -modfile=$(TESTMOD) .PHONY: fuzz fuzz: go test -fuzz=Fuzz -fuzztime 60s .PHONY: cover cover: go test -coverpkg=.,./ast,./lexer,./parser,./printer,./scanner,./token -coverprofile=cover.out -modfile=$(TESTMOD) ./... ./testdata .PHONY: cover-html cover-html: cover go tool cover -html=cover.out .PHONY: ycat/build ycat/build: $(LOCALBIN) cd ./cmd/ycat && go build -o $(LOCALBIN)/ycat . .PHONY: lint lint: golangci-lint ## Run golangci-lint @$(GOLANGCI_LINT) run .PHONY: fmt fmt: golangci-lint ## Ensure consistent code style @go mod tidy @go fmt ./... @$(GOLANGCI_LINT) run --fix ## Tool Binaries GOLANGCI_LINT ?= $(LOCALBIN)/golangci-lint ## Tool Versions GOLANGCI_VERSION := 2.1.2 .PHONY: golangci-lint .PHONY: $(GOLANGCI_LINT) golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. $(GOLANGCI_LINT): $(LOCALBIN) @test -s $(LOCALBIN)/golangci-lint && $(LOCALBIN)/golangci-lint version --short | grep -q $(GOLANGCI_VERSION) || \ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(LOCALBIN) v$(GOLANGCI_VERSION) goccy-go-yaml-52dacb8/README.md000066400000000000000000000323341501576637100161520ustar00rootroot00000000000000# YAML support for the Go language [![PkgGoDev](https://pkg.go.dev/badge/github.com/goccy/go-yaml)](https://pkg.go.dev/github.com/goccy/go-yaml) ![Go](https://github.com/goccy/go-yaml/workflows/Go/badge.svg) [![codecov](https://codecov.io/gh/goccy/go-yaml/branch/master/graph/badge.svg)](https://codecov.io/gh/goccy/go-yaml) [![Go Report Card](https://goreportcard.com/badge/github.com/goccy/go-yaml)](https://goreportcard.com/report/github.com/goccy/go-yaml) ## This library has **NO** relation to the go-yaml/yaml library > [!IMPORTANT] > This library is developed from scratch to replace [`go-yaml/yaml`](https://github.com/go-yaml/yaml). > If you're looking for a better YAML library, this one should be helpful. # Why a new library? As of this writing, there already exists a de facto standard library for YAML processing for Go: [https://github.com/go-yaml/yaml](https://github.com/go-yaml/yaml). However, we believe that a new YAML library is necessary for the following reasons: - Not actively maintained - `go-yaml/yaml` has ported the libyaml written in C to Go, so the source code is not written in Go style - There is a lot of content that cannot be parsed - YAML is often used for configuration, and it is common to include validation along with it. However, the errors in `go-yaml/yaml` are not intuitive, and it is difficult to provide meaningful validation errors - When creating tools that use YAML, there are cases where reversible transformation of YAML is required. However, to perform reversible transformations of content that includes Comments or Anchors/Aliases, manipulating the AST is the only option - Non-intuitive [Marshaler](https://pkg.go.dev/gopkg.in/yaml.v3#Marshaler) / [Unmarshaler](https://pkg.go.dev/gopkg.in/yaml.v3#Unmarshaler) By the way, libraries such as [ghodss/yaml](https://github.com/ghodss/yaml) and [sigs.k8s.io/yaml](https://github.com/kubernetes-sigs/yaml) also depend on go-yaml/yaml, so if you are using these libraries, the same issues apply: they cannot parse things that go-yaml/yaml cannot parse, and they inherit many of the problems that go-yaml/yaml has. # Features - No dependencies - A better parser than `go-yaml/yaml`. - [Support recursive processing](https://github.com/apple/device-management/blob/release/docs/schema.yaml) - Higher coverage in the [YAML Test Suite](https://github.com/yaml/yaml-test-suite?tab=readme-ov-file) - YAML Test Suite consists of 402 cases in total, of which `gopkg.in/yaml.v3` passes `295`. In addition to passing all those test cases, `goccy/go-yaml` successfully passes nearly 60 additional test cases ( 2024/12/15 ) - The test code is [here](https://github.com/goccy/go-yaml/blob/master/yaml_test_suite_test.go#L77) - Ease and sustainability of maintenance - The main maintainer is [@goccy](https://github.com/goccy), but we are also building a system to develop as a team with trusted developers - Since it is written from scratch, the code is easy to read for Gophers - An API structure that allows the use of not only `Encoder`/`Decoder` but also `Tokenizer` and `Parser` functionalities. - [lexer.Tokenize](https://pkg.go.dev/github.com/goccy/go-yaml@v1.15.4/lexer#Tokenize) - [parser.Parse](https://pkg.go.dev/github.com/goccy/go-yaml@v1.15.4/parser#Parse) - Filtering, replacing, and merging YAML content using YAML Path - Reversible transformation without using the AST for YAML that includes Anchors, Aliases, and Comments - Customize the Marshal/Unmarshal behavior for primitive types and third-party library types ([RegisterCustomMarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#RegisterCustomMarshaler), [RegisterCustomUnmarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#RegisterCustomUnmarshaler)) - Respects `encoding/json` behavior - Accept the `json` tag. Note that not all options from the `json` tag will have significance when parsing YAML documents. If both tags exist, `yaml` tag will take precedence. - [json.Marshaler](https://pkg.go.dev/encoding/json#Marshaler) style [marshaler](https://pkg.go.dev/github.com/goccy/go-yaml#BytesMarshaler) - [json.Unmarshaler](https://pkg.go.dev/encoding/json#Unmarshaler) style [unmarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#BytesUnmarshaler) - Options for using `MarshalJSON` and `UnmarshalJSON` ([UseJSONMarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#UseJSONMarshaler), [UseJSONUnmarshaler](https://pkg.go.dev/github.com/goccy/go-yaml#UseJSONUnmarshaler)) - Pretty format for error notifications - Smart validation processing combined with [go-playground/validator](https://github.com/go-playground/validator) - [example test code is here](https://github.com/goccy/go-yaml/blob/45889c98b0a0967240eb595a1bd6896e2f575106/testdata/validate_test.go#L12) - Allow referencing elements declared in another file via anchors # Users The repositories that use goccy/go-yaml are listed here. - https://github.com/goccy/go-yaml/wiki/Users The source data is [here](https://github.com/goccy/go-yaml/network/dependents). It is already being used in many repositories. Now it's your turn 😄 # Playground The Playground visualizes how go-yaml processes YAML text. Use it to assist with your debugging or issue reporting. https://goccy.github.io/go-yaml # Installation ```sh go get github.com/goccy/go-yaml ``` # Synopsis ## 1. Simple Encode/Decode Has an interface like `go-yaml/yaml` using `reflect` ```go var v struct { A int B string } v.A = 1 v.B = "hello" bytes, err := yaml.Marshal(v) if err != nil { //... } fmt.Println(string(bytes)) // "a: 1\nb: hello\n" ``` ```go yml := ` %YAML 1.2 --- a: 1 b: c ` var v struct { A int B string } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { //... } ``` To control marshal/unmarshal behavior, you can use the `yaml` tag. ```go yml := `--- foo: 1 bar: c ` var v struct { A int `yaml:"foo"` B string `yaml:"bar"` } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { //... } ``` For convenience, we also accept the `json` tag. Note that not all options from the `json` tag will have significance when parsing YAML documents. If both tags exist, `yaml` tag will take precedence. ```go yml := `--- foo: 1 bar: c ` var v struct { A int `json:"foo"` B string `json:"bar"` } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { //... } ``` For custom marshal/unmarshaling, implement either `Bytes` or `Interface` variant of marshaler/unmarshaler. The difference is that while `BytesMarshaler`/`BytesUnmarshaler` behaves like [`encoding/json`](https://pkg.go.dev/encoding/json) and `InterfaceMarshaler`/`InterfaceUnmarshaler` behaves like [`gopkg.in/yaml.v2`](https://pkg.go.dev/gopkg.in/yaml.v2). Semantically both are the same, but they differ in performance. Because indentation matters in YAML, you cannot simply accept a valid YAML fragment from a Marshaler, and expect it to work when it is attached to the parent container's serialized form. Therefore when we receive use the `BytesMarshaler`, which returns `[]byte`, we must decode it once to figure out how to make it work in the given context. If you use the `InterfaceMarshaler`, we can skip the decoding. If you are repeatedly marshaling complex objects, the latter is always better performance wise. But if you are, for example, just providing a choice between a config file format that is read only once, the former is probably easier to code. ## 2. Reference elements declared in another file `testdata` directory contains `anchor.yml` file: ```shell ├── testdata    └── anchor.yml ``` And `anchor.yml` is defined as follows: ```yaml a: &a b: 1 c: hello ``` Then, if `yaml.ReferenceDirs("testdata")` option is passed to `yaml.Decoder`, `Decoder` tries to find the anchor definition from YAML files the under `testdata` directory. ```go buf := bytes.NewBufferString("a: *a\n") dec := yaml.NewDecoder(buf, yaml.ReferenceDirs("testdata")) var v struct { A struct { B int C string } } if err := dec.Decode(&v); err != nil { //... } fmt.Printf("%+v\n", v) // {A:{B:1 C:hello}} ``` ## 3. Encode with `Anchor` and `Alias` ### 3.1. Explicitly declared `Anchor` name and `Alias` name If you want to use `anchor`, you can define it as a struct tag. If the value specified for an anchor is a pointer type and the same address as the pointer is found, the value is automatically set to alias. If an explicit alias name is specified, an error is raised if its value is different from the value specified in the anchor. ```go type T struct { A int B string } var v struct { C *T `yaml:"c,anchor=x"` D *T `yaml:"d,alias=x"` } v.C = &T{A: 1, B: "hello"} v.D = v.C bytes, err := yaml.Marshal(v) if err != nil { panic(err) } fmt.Println(string(bytes)) /* c: &x a: 1 b: hello d: *x */ ``` ### 3.2. Implicitly declared `Anchor` and `Alias` names If you do not explicitly declare the anchor name, the default behavior is to use the equivalent of `strings.ToLower($FieldName)` as the name of the anchor. If the value specified for an anchor is a pointer type and the same address as the pointer is found, the value is automatically set to alias. ```go type T struct { I int S string } var v struct { A *T `yaml:"a,anchor"` B *T `yaml:"b,anchor"` C *T `yaml:"c"` D *T `yaml:"d"` } v.A = &T{I: 1, S: "hello"} v.B = &T{I: 2, S: "world"} v.C = v.A // C has same pointer address to A v.D = v.B // D has same pointer address to B bytes, err := yaml.Marshal(v) if err != nil { //... } fmt.Println(string(bytes)) /* a: &a i: 1 s: hello b: &b i: 2 s: world c: *a d: *b */ ``` ### 3.3 MergeKey and Alias Merge key and alias ( `<<: *alias` ) can be used by embedding a structure with the `inline,alias` tag. ```go type Person struct { *Person `yaml:",omitempty,inline,alias"` // embed Person type for default value Name string `yaml:",omitempty"` Age int `yaml:",omitempty"` } defaultPerson := &Person{ Name: "John Smith", Age: 20, } people := []*Person{ { Person: defaultPerson, // assign default value Name: "Ken", // override Name property Age: 10, // override Age property }, { Person: defaultPerson, // assign default value only }, } var doc struct { Default *Person `yaml:"default,anchor"` People []*Person `yaml:"people"` } doc.Default = defaultPerson doc.People = people bytes, err := yaml.Marshal(doc) if err != nil { //... } fmt.Println(string(bytes)) /* default: &default name: John Smith age: 20 people: - <<: *default name: Ken age: 10 - <<: *default */ ``` ## 4. Pretty Formatted Errors Error values produced during parsing have two extra features over regular error values. First, by default, they contain extra information on the location of the error from the source YAML document, to make it easier to find the error location. Second, the error messages can optionally be colorized. If you would like to control exactly how the output looks like, consider using `yaml.FormatError`, which accepts two boolean values to control turning these features on or off. ## 5. Use YAMLPath ```go yml := ` store: book: - author: john price: 10 - author: ken price: 12 bicycle: color: red price: 19.95 ` path, err := yaml.PathString("$.store.book[*].author") if err != nil { //... } var authors []string if err := path.Read(strings.NewReader(yml), &authors); err != nil { //... } fmt.Println(authors) // [john ken] ``` ### 5.1 Print customized error with YAML source code ```go package main import ( "fmt" "github.com/goccy/go-yaml" ) func main() { yml := ` a: 1 b: "hello" ` var v struct { A int B string } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { panic(err) } if v.A != 2 { // output error with YAML source path, err := yaml.PathString("$.a") if err != nil { panic(err) } source, err := path.AnnotateSource([]byte(yml), true) if err != nil { panic(err) } fmt.Printf("a value expected 2 but actual %d:\n%s\n", v.A, string(source)) } } ``` output result is the following: # Tools ## ycat print yaml file with color ycat ### Installation ```sh git clone https://github.com/goccy/go-yaml.git cd go-yaml/cmd/ycat && go install . ``` # For Developers > [!NOTE] > In this project, we manage such test code under the `testdata` directory to avoid adding dependencies on libraries that are only needed for testing to the top `go.mod` file. Therefore, if you want to add test cases that use 3rd party libraries, please add the test code to the `testdata` directory. # Looking for Sponsors I'm looking for sponsors this library. This library is being developed as a personal project in my spare time. If you want a quick response or problem resolution when using this library in your project, please register as a [sponsor](https://github.com/sponsors/goccy). I will cooperate as much as possible. Of course, this library is developed as an MIT license, so you can use it freely for free. # License MIT goccy-go-yaml-52dacb8/ast/000077500000000000000000000000001501576637100154555ustar00rootroot00000000000000goccy-go-yaml-52dacb8/ast/ast.go000066400000000000000000001550131501576637100166000ustar00rootroot00000000000000package ast import ( "errors" "fmt" "io" "math" "strconv" "strings" "github.com/goccy/go-yaml/token" ) var ( ErrInvalidTokenType = errors.New("invalid token type") ErrInvalidAnchorName = errors.New("invalid anchor name") ErrInvalidAliasName = errors.New("invalid alias name") ) // NodeType type identifier of node type NodeType int const ( // UnknownNodeType type identifier for default UnknownNodeType NodeType = iota // DocumentType type identifier for document node DocumentType // NullType type identifier for null node NullType // BoolType type identifier for boolean node BoolType // IntegerType type identifier for integer node IntegerType // FloatType type identifier for float node FloatType // InfinityType type identifier for infinity node InfinityType // NanType type identifier for nan node NanType // StringType type identifier for string node StringType // MergeKeyType type identifier for merge key node MergeKeyType // LiteralType type identifier for literal node LiteralType // MappingType type identifier for mapping node MappingType // MappingKeyType type identifier for mapping key node MappingKeyType // MappingValueType type identifier for mapping value node MappingValueType // SequenceType type identifier for sequence node SequenceType // SequenceEntryType type identifier for sequence entry node SequenceEntryType // AnchorType type identifier for anchor node AnchorType // AliasType type identifier for alias node AliasType // DirectiveType type identifier for directive node DirectiveType // TagType type identifier for tag node TagType // CommentType type identifier for comment node CommentType // CommentGroupType type identifier for comment group node CommentGroupType ) // String node type identifier to text func (t NodeType) String() string { switch t { case UnknownNodeType: return "UnknownNode" case DocumentType: return "Document" case NullType: return "Null" case BoolType: return "Bool" case IntegerType: return "Integer" case FloatType: return "Float" case InfinityType: return "Infinity" case NanType: return "Nan" case StringType: return "String" case MergeKeyType: return "MergeKey" case LiteralType: return "Literal" case MappingType: return "Mapping" case MappingKeyType: return "MappingKey" case MappingValueType: return "MappingValue" case SequenceType: return "Sequence" case SequenceEntryType: return "SequenceEntry" case AnchorType: return "Anchor" case AliasType: return "Alias" case DirectiveType: return "Directive" case TagType: return "Tag" case CommentType: return "Comment" case CommentGroupType: return "CommentGroup" } return "" } // String node type identifier to YAML Structure name // based on https://yaml.org/spec/1.2/spec.html func (t NodeType) YAMLName() string { switch t { case UnknownNodeType: return "unknown" case DocumentType: return "document" case NullType: return "null" case BoolType: return "boolean" case IntegerType: return "int" case FloatType: return "float" case InfinityType: return "inf" case NanType: return "nan" case StringType: return "string" case MergeKeyType: return "merge key" case LiteralType: return "scalar" case MappingType: return "mapping" case MappingKeyType: return "key" case MappingValueType: return "value" case SequenceType: return "sequence" case SequenceEntryType: return "value" case AnchorType: return "anchor" case AliasType: return "alias" case DirectiveType: return "directive" case TagType: return "tag" case CommentType: return "comment" case CommentGroupType: return "comment" } return "" } // Node type of node type Node interface { io.Reader // String node to text String() string // GetToken returns token instance GetToken() *token.Token // Type returns type of node Type() NodeType // AddColumn add column number to child nodes recursively AddColumn(int) // SetComment set comment token to node SetComment(*CommentGroupNode) error // Comment returns comment token instance GetComment() *CommentGroupNode // GetPath returns YAMLPath for the current node GetPath() string // SetPath set YAMLPath for the current node SetPath(string) // MarshalYAML MarshalYAML() ([]byte, error) // already read length readLen() int // append read length addReadLen(int) // clean read length clearLen() } // MapKeyNode type for map key node type MapKeyNode interface { Node IsMergeKey() bool // String node to text without comment stringWithoutComment() string } // ScalarNode type for scalar node type ScalarNode interface { MapKeyNode GetValue() interface{} } type BaseNode struct { Path string Comment *CommentGroupNode read int } func addCommentString(base string, node *CommentGroupNode) string { return fmt.Sprintf("%s %s", base, node.String()) } func (n *BaseNode) readLen() int { return n.read } func (n *BaseNode) clearLen() { n.read = 0 } func (n *BaseNode) addReadLen(len int) { n.read += len } // GetPath returns YAMLPath for the current node. func (n *BaseNode) GetPath() string { if n == nil { return "" } return n.Path } // SetPath set YAMLPath for the current node. func (n *BaseNode) SetPath(path string) { if n == nil { return } n.Path = path } // GetComment returns comment token instance func (n *BaseNode) GetComment() *CommentGroupNode { return n.Comment } // SetComment set comment token func (n *BaseNode) SetComment(node *CommentGroupNode) error { n.Comment = node return nil } func min(a, b int) int { if a < b { return a } return b } func readNode(p []byte, node Node) (int, error) { s := node.String() readLen := node.readLen() remain := len(s) - readLen if remain == 0 { node.clearLen() return 0, io.EOF } size := min(remain, len(p)) for idx, b := range []byte(s[readLen : readLen+size]) { p[idx] = byte(b) } node.addReadLen(size) return size, nil } func checkLineBreak(t *token.Token) bool { if t.Prev != nil { lbc := "\n" prev := t.Prev var adjustment int // if the previous type is sequence entry use the previous type for that if prev.Type == token.SequenceEntryType { // as well as switching to previous type count any new lines in origin to account for: // - // b: c adjustment = strings.Count(strings.TrimRight(t.Origin, lbc), lbc) if prev.Prev != nil { prev = prev.Prev } } lineDiff := t.Position.Line - prev.Position.Line - 1 if lineDiff > 0 { if prev.Type == token.StringType { // Remove any line breaks included in multiline string adjustment += strings.Count(strings.TrimRight(strings.TrimSpace(prev.Origin), lbc), lbc) } // Due to the way that comment parsing works its assumed that when a null value does not have new line in origin // it was squashed therefore difference is ignored. // foo: // bar: // # comment // baz: 1 // becomes // foo: // bar: null # comment // // baz: 1 if prev.Type == token.NullType || prev.Type == token.ImplicitNullType { return strings.Count(prev.Origin, lbc) > 0 } if lineDiff-adjustment > 0 { return true } } } return false } // Null create node for null value func Null(tk *token.Token) *NullNode { return &NullNode{ BaseNode: &BaseNode{}, Token: tk, } } // Bool create node for boolean value func Bool(tk *token.Token) *BoolNode { b, _ := strconv.ParseBool(tk.Value) return &BoolNode{ BaseNode: &BaseNode{}, Token: tk, Value: b, } } // Integer create node for integer value func Integer(tk *token.Token) *IntegerNode { var v any if num := token.ToNumber(tk.Value); num != nil { v = num.Value } return &IntegerNode{ BaseNode: &BaseNode{}, Token: tk, Value: v, } } // Float create node for float value func Float(tk *token.Token) *FloatNode { var v float64 if num := token.ToNumber(tk.Value); num != nil && num.Type == token.NumberTypeFloat { value, ok := num.Value.(float64) if ok { v = value } } return &FloatNode{ BaseNode: &BaseNode{}, Token: tk, Value: v, } } // Infinity create node for .inf or -.inf value func Infinity(tk *token.Token) *InfinityNode { node := &InfinityNode{ BaseNode: &BaseNode{}, Token: tk, } switch tk.Value { case ".inf", ".Inf", ".INF": node.Value = math.Inf(0) case "-.inf", "-.Inf", "-.INF": node.Value = math.Inf(-1) } return node } // Nan create node for .nan value func Nan(tk *token.Token) *NanNode { return &NanNode{ BaseNode: &BaseNode{}, Token: tk, } } // String create node for string value func String(tk *token.Token) *StringNode { return &StringNode{ BaseNode: &BaseNode{}, Token: tk, Value: tk.Value, } } // Comment create node for comment func Comment(tk *token.Token) *CommentNode { return &CommentNode{ BaseNode: &BaseNode{}, Token: tk, } } func CommentGroup(comments []*token.Token) *CommentGroupNode { nodes := []*CommentNode{} for _, comment := range comments { nodes = append(nodes, Comment(comment)) } return &CommentGroupNode{ BaseNode: &BaseNode{}, Comments: nodes, } } // MergeKey create node for merge key ( << ) func MergeKey(tk *token.Token) *MergeKeyNode { return &MergeKeyNode{ BaseNode: &BaseNode{}, Token: tk, } } // Mapping create node for map func Mapping(tk *token.Token, isFlowStyle bool, values ...*MappingValueNode) *MappingNode { node := &MappingNode{ BaseNode: &BaseNode{}, Start: tk, IsFlowStyle: isFlowStyle, Values: []*MappingValueNode{}, } node.Values = append(node.Values, values...) return node } // MappingValue create node for mapping value func MappingValue(tk *token.Token, key MapKeyNode, value Node) *MappingValueNode { return &MappingValueNode{ BaseNode: &BaseNode{}, Start: tk, Key: key, Value: value, } } // MappingKey create node for map key ( '?' ). func MappingKey(tk *token.Token) *MappingKeyNode { return &MappingKeyNode{ BaseNode: &BaseNode{}, Start: tk, } } // Sequence create node for sequence func Sequence(tk *token.Token, isFlowStyle bool) *SequenceNode { return &SequenceNode{ BaseNode: &BaseNode{}, Start: tk, IsFlowStyle: isFlowStyle, Values: []Node{}, } } func Anchor(tk *token.Token) *AnchorNode { return &AnchorNode{ BaseNode: &BaseNode{}, Start: tk, } } func Alias(tk *token.Token) *AliasNode { return &AliasNode{ BaseNode: &BaseNode{}, Start: tk, } } func Document(tk *token.Token, body Node) *DocumentNode { return &DocumentNode{ BaseNode: &BaseNode{}, Start: tk, Body: body, } } func Directive(tk *token.Token) *DirectiveNode { return &DirectiveNode{ BaseNode: &BaseNode{}, Start: tk, } } func Literal(tk *token.Token) *LiteralNode { return &LiteralNode{ BaseNode: &BaseNode{}, Start: tk, } } func Tag(tk *token.Token) *TagNode { return &TagNode{ BaseNode: &BaseNode{}, Start: tk, } } // File contains all documents in YAML file type File struct { Name string Docs []*DocumentNode } // Read implements (io.Reader).Read func (f *File) Read(p []byte) (int, error) { for _, doc := range f.Docs { n, err := doc.Read(p) if err == io.EOF { continue } return n, nil } return 0, io.EOF } // String all documents to text func (f *File) String() string { docs := []string{} for _, doc := range f.Docs { docs = append(docs, doc.String()) } if len(docs) > 0 { return strings.Join(docs, "\n") + "\n" } else { return "" } } // DocumentNode type of Document type DocumentNode struct { *BaseNode Start *token.Token // position of DocumentHeader ( `---` ) End *token.Token // position of DocumentEnd ( `...` ) Body Node } // Read implements (io.Reader).Read func (d *DocumentNode) Read(p []byte) (int, error) { return readNode(p, d) } // Type returns DocumentNodeType func (d *DocumentNode) Type() NodeType { return DocumentType } // GetToken returns token instance func (d *DocumentNode) GetToken() *token.Token { return d.Body.GetToken() } // AddColumn add column number to child nodes recursively func (d *DocumentNode) AddColumn(col int) { if d.Body != nil { d.Body.AddColumn(col) } } // String document to text func (d *DocumentNode) String() string { doc := []string{} if d.Start != nil { doc = append(doc, d.Start.Value) } if d.Body != nil { doc = append(doc, d.Body.String()) } if d.End != nil { doc = append(doc, d.End.Value) } return strings.Join(doc, "\n") } // MarshalYAML encodes to a YAML text func (d *DocumentNode) MarshalYAML() ([]byte, error) { return []byte(d.String()), nil } // NullNode type of null node type NullNode struct { *BaseNode Token *token.Token } // Read implements (io.Reader).Read func (n *NullNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns NullType func (n *NullNode) Type() NodeType { return NullType } // GetToken returns token instance func (n *NullNode) GetToken() *token.Token { return n.Token } // AddColumn add column number to child nodes recursively func (n *NullNode) AddColumn(col int) { n.Token.AddColumn(col) } // GetValue returns nil value func (n *NullNode) GetValue() interface{} { return nil } // String returns `null` text func (n *NullNode) String() string { if n.Token.Type == token.ImplicitNullType { if n.Comment != nil { return n.Comment.String() } return "" } if n.Comment != nil { return addCommentString("null", n.Comment) } return n.stringWithoutComment() } func (n *NullNode) stringWithoutComment() string { return "null" } // MarshalYAML encodes to a YAML text func (n *NullNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *NullNode) IsMergeKey() bool { return false } // IntegerNode type of integer node type IntegerNode struct { *BaseNode Token *token.Token Value interface{} // int64 or uint64 value } // Read implements (io.Reader).Read func (n *IntegerNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns IntegerType func (n *IntegerNode) Type() NodeType { return IntegerType } // GetToken returns token instance func (n *IntegerNode) GetToken() *token.Token { return n.Token } // AddColumn add column number to child nodes recursively func (n *IntegerNode) AddColumn(col int) { n.Token.AddColumn(col) } // GetValue returns int64 value func (n *IntegerNode) GetValue() interface{} { return n.Value } // String int64 to text func (n *IntegerNode) String() string { if n.Comment != nil { return addCommentString(n.Token.Value, n.Comment) } return n.stringWithoutComment() } func (n *IntegerNode) stringWithoutComment() string { return n.Token.Value } // MarshalYAML encodes to a YAML text func (n *IntegerNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *IntegerNode) IsMergeKey() bool { return false } // FloatNode type of float node type FloatNode struct { *BaseNode Token *token.Token Precision int Value float64 } // Read implements (io.Reader).Read func (n *FloatNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns FloatType func (n *FloatNode) Type() NodeType { return FloatType } // GetToken returns token instance func (n *FloatNode) GetToken() *token.Token { return n.Token } // AddColumn add column number to child nodes recursively func (n *FloatNode) AddColumn(col int) { n.Token.AddColumn(col) } // GetValue returns float64 value func (n *FloatNode) GetValue() interface{} { return n.Value } // String float64 to text func (n *FloatNode) String() string { if n.Comment != nil { return addCommentString(n.Token.Value, n.Comment) } return n.stringWithoutComment() } func (n *FloatNode) stringWithoutComment() string { return n.Token.Value } // MarshalYAML encodes to a YAML text func (n *FloatNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *FloatNode) IsMergeKey() bool { return false } // StringNode type of string node type StringNode struct { *BaseNode Token *token.Token Value string } // Read implements (io.Reader).Read func (n *StringNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns StringType func (n *StringNode) Type() NodeType { return StringType } // GetToken returns token instance func (n *StringNode) GetToken() *token.Token { return n.Token } // AddColumn add column number to child nodes recursively func (n *StringNode) AddColumn(col int) { n.Token.AddColumn(col) } // GetValue returns string value func (n *StringNode) GetValue() interface{} { return n.Value } // IsMergeKey returns whether it is a MergeKey node. func (n *StringNode) IsMergeKey() bool { return false } // escapeSingleQuote escapes s to a single quoted scalar. // https://yaml.org/spec/1.2.2/#732-single-quoted-style func escapeSingleQuote(s string) string { var sb strings.Builder growLen := len(s) + // s includes also one ' from the doubled pair 2 + // opening and closing ' strings.Count(s, "'") // ' added by ReplaceAll sb.Grow(growLen) sb.WriteString("'") sb.WriteString(strings.ReplaceAll(s, "'", "''")) sb.WriteString("'") return sb.String() } // String string value to text with quote or literal header if required func (n *StringNode) String() string { switch n.Token.Type { case token.SingleQuoteType: quoted := escapeSingleQuote(n.Value) if n.Comment != nil { return addCommentString(quoted, n.Comment) } return quoted case token.DoubleQuoteType: quoted := strconv.Quote(n.Value) if n.Comment != nil { return addCommentString(quoted, n.Comment) } return quoted } lbc := token.DetectLineBreakCharacter(n.Value) if strings.Contains(n.Value, lbc) { // This block assumes that the line breaks in this inside scalar content and the Outside scalar content are the same. // It works mostly, but inconsistencies occur if line break characters are mixed. header := token.LiteralBlockHeader(n.Value) space := strings.Repeat(" ", n.Token.Position.Column-1) indent := strings.Repeat(" ", n.Token.Position.IndentNum) values := []string{} for _, v := range strings.Split(n.Value, lbc) { values = append(values, fmt.Sprintf("%s%s%s", space, indent, v)) } block := strings.TrimSuffix(strings.TrimSuffix(strings.Join(values, lbc), fmt.Sprintf("%s%s%s", lbc, indent, space)), fmt.Sprintf("%s%s", indent, space)) return fmt.Sprintf("%s%s%s", header, lbc, block) } else if len(n.Value) > 0 && (n.Value[0] == '{' || n.Value[0] == '[') { return fmt.Sprintf(`'%s'`, n.Value) } if n.Comment != nil { return addCommentString(n.Value, n.Comment) } return n.Value } func (n *StringNode) stringWithoutComment() string { switch n.Token.Type { case token.SingleQuoteType: quoted := fmt.Sprintf(`'%s'`, n.Value) return quoted case token.DoubleQuoteType: quoted := strconv.Quote(n.Value) return quoted } lbc := token.DetectLineBreakCharacter(n.Value) if strings.Contains(n.Value, lbc) { // This block assumes that the line breaks in this inside scalar content and the Outside scalar content are the same. // It works mostly, but inconsistencies occur if line break characters are mixed. header := token.LiteralBlockHeader(n.Value) space := strings.Repeat(" ", n.Token.Position.Column-1) indent := strings.Repeat(" ", n.Token.Position.IndentNum) values := []string{} for _, v := range strings.Split(n.Value, lbc) { values = append(values, fmt.Sprintf("%s%s%s", space, indent, v)) } block := strings.TrimSuffix(strings.TrimSuffix(strings.Join(values, lbc), fmt.Sprintf("%s%s%s", lbc, indent, space)), fmt.Sprintf(" %s", space)) return fmt.Sprintf("%s%s%s", header, lbc, block) } else if len(n.Value) > 0 && (n.Value[0] == '{' || n.Value[0] == '[') { return fmt.Sprintf(`'%s'`, n.Value) } return n.Value } // MarshalYAML encodes to a YAML text func (n *StringNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // LiteralNode type of literal node type LiteralNode struct { *BaseNode Start *token.Token Value *StringNode } // Read implements (io.Reader).Read func (n *LiteralNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns LiteralType func (n *LiteralNode) Type() NodeType { return LiteralType } // GetToken returns token instance func (n *LiteralNode) GetToken() *token.Token { return n.Start } // AddColumn add column number to child nodes recursively func (n *LiteralNode) AddColumn(col int) { n.Start.AddColumn(col) if n.Value != nil { n.Value.AddColumn(col) } } // GetValue returns string value func (n *LiteralNode) GetValue() interface{} { return n.String() } // String literal to text func (n *LiteralNode) String() string { origin := n.Value.GetToken().Origin lit := strings.TrimRight(strings.TrimRight(origin, " "), "\n") if n.Comment != nil { return fmt.Sprintf("%s %s\n%s", n.Start.Value, n.Comment.String(), lit) } return fmt.Sprintf("%s\n%s", n.Start.Value, lit) } func (n *LiteralNode) stringWithoutComment() string { return n.String() } // MarshalYAML encodes to a YAML text func (n *LiteralNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *LiteralNode) IsMergeKey() bool { return false } // MergeKeyNode type of merge key node type MergeKeyNode struct { *BaseNode Token *token.Token } // Read implements (io.Reader).Read func (n *MergeKeyNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns MergeKeyType func (n *MergeKeyNode) Type() NodeType { return MergeKeyType } // GetToken returns token instance func (n *MergeKeyNode) GetToken() *token.Token { return n.Token } // GetValue returns '<<' value func (n *MergeKeyNode) GetValue() interface{} { return n.Token.Value } // String returns '<<' value func (n *MergeKeyNode) String() string { return n.stringWithoutComment() } func (n *MergeKeyNode) stringWithoutComment() string { return n.Token.Value } // AddColumn add column number to child nodes recursively func (n *MergeKeyNode) AddColumn(col int) { n.Token.AddColumn(col) } // MarshalYAML encodes to a YAML text func (n *MergeKeyNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *MergeKeyNode) IsMergeKey() bool { return true } // BoolNode type of boolean node type BoolNode struct { *BaseNode Token *token.Token Value bool } // Read implements (io.Reader).Read func (n *BoolNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns BoolType func (n *BoolNode) Type() NodeType { return BoolType } // GetToken returns token instance func (n *BoolNode) GetToken() *token.Token { return n.Token } // AddColumn add column number to child nodes recursively func (n *BoolNode) AddColumn(col int) { n.Token.AddColumn(col) } // GetValue returns boolean value func (n *BoolNode) GetValue() interface{} { return n.Value } // String boolean to text func (n *BoolNode) String() string { if n.Comment != nil { return addCommentString(n.Token.Value, n.Comment) } return n.stringWithoutComment() } func (n *BoolNode) stringWithoutComment() string { return n.Token.Value } // MarshalYAML encodes to a YAML text func (n *BoolNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *BoolNode) IsMergeKey() bool { return false } // InfinityNode type of infinity node type InfinityNode struct { *BaseNode Token *token.Token Value float64 } // Read implements (io.Reader).Read func (n *InfinityNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns InfinityType func (n *InfinityNode) Type() NodeType { return InfinityType } // GetToken returns token instance func (n *InfinityNode) GetToken() *token.Token { return n.Token } // AddColumn add column number to child nodes recursively func (n *InfinityNode) AddColumn(col int) { n.Token.AddColumn(col) } // GetValue returns math.Inf(0) or math.Inf(-1) func (n *InfinityNode) GetValue() interface{} { return n.Value } // String infinity to text func (n *InfinityNode) String() string { if n.Comment != nil { return addCommentString(n.Token.Value, n.Comment) } return n.stringWithoutComment() } func (n *InfinityNode) stringWithoutComment() string { return n.Token.Value } // MarshalYAML encodes to a YAML text func (n *InfinityNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *InfinityNode) IsMergeKey() bool { return false } // NanNode type of nan node type NanNode struct { *BaseNode Token *token.Token } // Read implements (io.Reader).Read func (n *NanNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns NanType func (n *NanNode) Type() NodeType { return NanType } // GetToken returns token instance func (n *NanNode) GetToken() *token.Token { return n.Token } // AddColumn add column number to child nodes recursively func (n *NanNode) AddColumn(col int) { n.Token.AddColumn(col) } // GetValue returns math.NaN() func (n *NanNode) GetValue() interface{} { return math.NaN() } // String returns .nan func (n *NanNode) String() string { if n.Comment != nil { return addCommentString(n.Token.Value, n.Comment) } return n.stringWithoutComment() } func (n *NanNode) stringWithoutComment() string { return n.Token.Value } // MarshalYAML encodes to a YAML text func (n *NanNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *NanNode) IsMergeKey() bool { return false } // MapNode interface of MappingValueNode / MappingNode type MapNode interface { MapRange() *MapNodeIter } // MapNodeIter is an iterator for ranging over a MapNode type MapNodeIter struct { values []*MappingValueNode idx int } const ( startRangeIndex = -1 ) // Next advances the map iterator and reports whether there is another entry. // It returns false when the iterator is exhausted. func (m *MapNodeIter) Next() bool { m.idx++ next := m.idx < len(m.values) return next } // Key returns the key of the iterator's current map node entry. func (m *MapNodeIter) Key() MapKeyNode { return m.values[m.idx].Key } // Value returns the value of the iterator's current map node entry. func (m *MapNodeIter) Value() Node { return m.values[m.idx].Value } // KeyValue returns the MappingValueNode of the iterator's current map node entry. func (m *MapNodeIter) KeyValue() *MappingValueNode { return m.values[m.idx] } // MappingNode type of mapping node type MappingNode struct { *BaseNode Start *token.Token End *token.Token IsFlowStyle bool Values []*MappingValueNode FootComment *CommentGroupNode } func (n *MappingNode) startPos() *token.Position { if len(n.Values) == 0 { return n.Start.Position } return n.Values[0].Key.GetToken().Position } // Merge merge key/value of map. func (n *MappingNode) Merge(target *MappingNode) { keyToMapValueMap := map[string]*MappingValueNode{} for _, value := range n.Values { key := value.Key.String() keyToMapValueMap[key] = value } column := n.startPos().Column - target.startPos().Column target.AddColumn(column) for _, value := range target.Values { mapValue, exists := keyToMapValueMap[value.Key.String()] if exists { mapValue.Value = value.Value } else { n.Values = append(n.Values, value) } } } // SetIsFlowStyle set value to IsFlowStyle field recursively. func (n *MappingNode) SetIsFlowStyle(isFlow bool) { n.IsFlowStyle = isFlow for _, value := range n.Values { value.SetIsFlowStyle(isFlow) } } // Read implements (io.Reader).Read func (n *MappingNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns MappingType func (n *MappingNode) Type() NodeType { return MappingType } // GetToken returns token instance func (n *MappingNode) GetToken() *token.Token { return n.Start } // AddColumn add column number to child nodes recursively func (n *MappingNode) AddColumn(col int) { n.Start.AddColumn(col) n.End.AddColumn(col) for _, value := range n.Values { value.AddColumn(col) } } func (n *MappingNode) flowStyleString(commentMode bool) string { values := []string{} for _, value := range n.Values { values = append(values, strings.TrimLeft(value.String(), " ")) } mapText := fmt.Sprintf("{%s}", strings.Join(values, ", ")) if commentMode && n.Comment != nil { return addCommentString(mapText, n.Comment) } return mapText } func (n *MappingNode) blockStyleString(commentMode bool) string { values := []string{} for _, value := range n.Values { values = append(values, value.String()) } mapText := strings.Join(values, "\n") if commentMode && n.Comment != nil { value := values[0] var spaceNum int for i := 0; i < len(value); i++ { if value[i] != ' ' { break } spaceNum++ } comment := n.Comment.StringWithSpace(spaceNum) return fmt.Sprintf("%s\n%s", comment, mapText) } return mapText } // String mapping values to text func (n *MappingNode) String() string { if len(n.Values) == 0 { if n.Comment != nil { return addCommentString("{}", n.Comment) } return "{}" } commentMode := true if n.IsFlowStyle || len(n.Values) == 0 { return n.flowStyleString(commentMode) } return n.blockStyleString(commentMode) } // MapRange implements MapNode protocol func (n *MappingNode) MapRange() *MapNodeIter { return &MapNodeIter{ idx: startRangeIndex, values: n.Values, } } // MarshalYAML encodes to a YAML text func (n *MappingNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // MappingKeyNode type of tag node type MappingKeyNode struct { *BaseNode Start *token.Token Value Node } // Read implements (io.Reader).Read func (n *MappingKeyNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns MappingKeyType func (n *MappingKeyNode) Type() NodeType { return MappingKeyType } // GetToken returns token instance func (n *MappingKeyNode) GetToken() *token.Token { return n.Start } // AddColumn add column number to child nodes recursively func (n *MappingKeyNode) AddColumn(col int) { n.Start.AddColumn(col) if n.Value != nil { n.Value.AddColumn(col) } } // String tag to text func (n *MappingKeyNode) String() string { return n.stringWithoutComment() } func (n *MappingKeyNode) stringWithoutComment() string { return fmt.Sprintf("%s %s", n.Start.Value, n.Value.String()) } // MarshalYAML encodes to a YAML text func (n *MappingKeyNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *MappingKeyNode) IsMergeKey() bool { if n.Value == nil { return false } key, ok := n.Value.(MapKeyNode) if !ok { return false } return key.IsMergeKey() } // MappingValueNode type of mapping value type MappingValueNode struct { *BaseNode Start *token.Token // delimiter token ':'. CollectEntry *token.Token // collect entry token ','. Key MapKeyNode Value Node FootComment *CommentGroupNode IsFlowStyle bool } // Replace replace value node. func (n *MappingValueNode) Replace(value Node) error { column := n.Value.GetToken().Position.Column - value.GetToken().Position.Column value.AddColumn(column) n.Value = value return nil } // Read implements (io.Reader).Read func (n *MappingValueNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns MappingValueType func (n *MappingValueNode) Type() NodeType { return MappingValueType } // GetToken returns token instance func (n *MappingValueNode) GetToken() *token.Token { return n.Start } // AddColumn add column number to child nodes recursively func (n *MappingValueNode) AddColumn(col int) { n.Start.AddColumn(col) if n.Key != nil { n.Key.AddColumn(col) } if n.Value != nil { n.Value.AddColumn(col) } } // SetIsFlowStyle set value to IsFlowStyle field recursively. func (n *MappingValueNode) SetIsFlowStyle(isFlow bool) { n.IsFlowStyle = isFlow switch value := n.Value.(type) { case *MappingNode: value.SetIsFlowStyle(isFlow) case *MappingValueNode: value.SetIsFlowStyle(isFlow) case *SequenceNode: value.SetIsFlowStyle(isFlow) } } // String mapping value to text func (n *MappingValueNode) String() string { var text string if n.Comment != nil { text = fmt.Sprintf( "%s\n%s", n.Comment.StringWithSpace(n.Key.GetToken().Position.Column-1), n.toString(), ) } else { text = n.toString() } if n.FootComment != nil { text += fmt.Sprintf("\n%s", n.FootComment.StringWithSpace(n.Key.GetToken().Position.Column-1)) } return text } func (n *MappingValueNode) toString() string { space := strings.Repeat(" ", n.Key.GetToken().Position.Column-1) if checkLineBreak(n.Key.GetToken()) { space = fmt.Sprintf("%s%s", "\n", space) } keyIndentLevel := n.Key.GetToken().Position.IndentLevel valueIndentLevel := n.Value.GetToken().Position.IndentLevel keyComment := n.Key.GetComment() if _, ok := n.Value.(ScalarNode); ok { value := n.Value.String() if value == "" { // implicit null value. return fmt.Sprintf("%s%s:", space, n.Key.String()) } return fmt.Sprintf("%s%s: %s", space, n.Key.String(), value) } else if keyIndentLevel < valueIndentLevel && !n.IsFlowStyle { if keyComment != nil { return fmt.Sprintf( "%s%s: %s\n%s", space, n.Key.stringWithoutComment(), keyComment.String(), n.Value.String(), ) } return fmt.Sprintf("%s%s:\n%s", space, n.Key.String(), n.Value.String()) } else if m, ok := n.Value.(*MappingNode); ok && (m.IsFlowStyle || len(m.Values) == 0) { return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String()) } else if s, ok := n.Value.(*SequenceNode); ok && (s.IsFlowStyle || len(s.Values) == 0) { return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String()) } else if _, ok := n.Value.(*AnchorNode); ok { return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String()) } else if _, ok := n.Value.(*AliasNode); ok { return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String()) } else if _, ok := n.Value.(*TagNode); ok { return fmt.Sprintf("%s%s: %s", space, n.Key.String(), n.Value.String()) } if keyComment != nil { return fmt.Sprintf( "%s%s: %s\n%s", space, n.Key.stringWithoutComment(), keyComment.String(), n.Value.String(), ) } if m, ok := n.Value.(*MappingNode); ok && m.Comment != nil { return fmt.Sprintf( "%s%s: %s", space, n.Key.String(), strings.TrimLeft(n.Value.String(), " "), ) } return fmt.Sprintf("%s%s:\n%s", space, n.Key.String(), n.Value.String()) } // MapRange implements MapNode protocol func (n *MappingValueNode) MapRange() *MapNodeIter { return &MapNodeIter{ idx: startRangeIndex, values: []*MappingValueNode{n}, } } // MarshalYAML encodes to a YAML text func (n *MappingValueNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // ArrayNode interface of SequenceNode type ArrayNode interface { ArrayRange() *ArrayNodeIter } // ArrayNodeIter is an iterator for ranging over a ArrayNode type ArrayNodeIter struct { values []Node idx int } // Next advances the array iterator and reports whether there is another entry. // It returns false when the iterator is exhausted. func (m *ArrayNodeIter) Next() bool { m.idx++ next := m.idx < len(m.values) return next } // Value returns the value of the iterator's current array entry. func (m *ArrayNodeIter) Value() Node { return m.values[m.idx] } // Len returns length of array func (m *ArrayNodeIter) Len() int { return len(m.values) } // SequenceNode type of sequence node type SequenceNode struct { *BaseNode Start *token.Token End *token.Token IsFlowStyle bool Values []Node ValueHeadComments []*CommentGroupNode Entries []*SequenceEntryNode FootComment *CommentGroupNode } // Replace replace value node. func (n *SequenceNode) Replace(idx int, value Node) error { if len(n.Values) <= idx { return fmt.Errorf( "invalid index for sequence: sequence length is %d, but specified %d index", len(n.Values), idx, ) } column := n.Values[idx].GetToken().Position.Column - value.GetToken().Position.Column value.AddColumn(column) n.Values[idx] = value return nil } // Merge merge sequence value. func (n *SequenceNode) Merge(target *SequenceNode) { column := n.Start.Position.Column - target.Start.Position.Column target.AddColumn(column) n.Values = append(n.Values, target.Values...) if len(target.ValueHeadComments) == 0 { n.ValueHeadComments = append(n.ValueHeadComments, make([]*CommentGroupNode, len(target.Values))...) return } n.ValueHeadComments = append(n.ValueHeadComments, target.ValueHeadComments...) } // SetIsFlowStyle set value to IsFlowStyle field recursively. func (n *SequenceNode) SetIsFlowStyle(isFlow bool) { n.IsFlowStyle = isFlow for _, value := range n.Values { switch value := value.(type) { case *MappingNode: value.SetIsFlowStyle(isFlow) case *MappingValueNode: value.SetIsFlowStyle(isFlow) case *SequenceNode: value.SetIsFlowStyle(isFlow) } } } // Read implements (io.Reader).Read func (n *SequenceNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns SequenceType func (n *SequenceNode) Type() NodeType { return SequenceType } // GetToken returns token instance func (n *SequenceNode) GetToken() *token.Token { return n.Start } // AddColumn add column number to child nodes recursively func (n *SequenceNode) AddColumn(col int) { n.Start.AddColumn(col) n.End.AddColumn(col) for _, value := range n.Values { value.AddColumn(col) } } func (n *SequenceNode) flowStyleString() string { values := []string{} for _, value := range n.Values { values = append(values, value.String()) } return fmt.Sprintf("[%s]", strings.Join(values, ", ")) } func (n *SequenceNode) blockStyleString() string { space := strings.Repeat(" ", n.Start.Position.Column-1) values := []string{} if n.Comment != nil { values = append(values, n.Comment.StringWithSpace(n.Start.Position.Column-1)) } for idx, value := range n.Values { if value == nil { continue } valueStr := value.String() newLinePrefix := "" if strings.HasPrefix(valueStr, "\n") { valueStr = valueStr[1:] newLinePrefix = "\n" } splittedValues := strings.Split(valueStr, "\n") trimmedFirstValue := strings.TrimLeft(splittedValues[0], " ") diffLength := len(splittedValues[0]) - len(trimmedFirstValue) if len(splittedValues) > 1 && value.Type() == StringType || value.Type() == LiteralType { // If multi-line string, the space characters for indent have already been added, so delete them. prefix := space + " " for i := 1; i < len(splittedValues); i++ { splittedValues[i] = strings.TrimPrefix(splittedValues[i], prefix) } } newValues := []string{trimmedFirstValue} for i := 1; i < len(splittedValues); i++ { if len(splittedValues[i]) <= diffLength { // this line is \n or white space only newValues = append(newValues, "") continue } trimmed := splittedValues[i][diffLength:] newValues = append(newValues, fmt.Sprintf("%s %s", space, trimmed)) } newValue := strings.Join(newValues, "\n") if len(n.ValueHeadComments) == len(n.Values) && n.ValueHeadComments[idx] != nil { values = append(values, fmt.Sprintf("%s%s", newLinePrefix, n.ValueHeadComments[idx].StringWithSpace(n.Start.Position.Column-1))) newLinePrefix = "" } values = append(values, fmt.Sprintf("%s%s- %s", newLinePrefix, space, newValue)) } if n.FootComment != nil { values = append(values, n.FootComment.StringWithSpace(n.Start.Position.Column-1)) } return strings.Join(values, "\n") } // String sequence to text func (n *SequenceNode) String() string { if n.IsFlowStyle || len(n.Values) == 0 { return n.flowStyleString() } return n.blockStyleString() } // ArrayRange implements ArrayNode protocol func (n *SequenceNode) ArrayRange() *ArrayNodeIter { return &ArrayNodeIter{ idx: startRangeIndex, values: n.Values, } } // MarshalYAML encodes to a YAML text func (n *SequenceNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // SequenceEntryNode is the sequence entry. type SequenceEntryNode struct { *BaseNode HeadComment *CommentGroupNode // head comment. LineComment *CommentGroupNode // line comment e.g.) - # comment. Start *token.Token // entry token. Value Node // value node. } // String node to text func (n *SequenceEntryNode) String() string { return "" // TODO } // GetToken returns token instance func (n *SequenceEntryNode) GetToken() *token.Token { return n.Start } // Type returns type of node func (n *SequenceEntryNode) Type() NodeType { return SequenceEntryType } // AddColumn add column number to child nodes recursively func (n *SequenceEntryNode) AddColumn(col int) { n.Start.AddColumn(col) } // SetComment set line comment. func (n *SequenceEntryNode) SetComment(cm *CommentGroupNode) error { n.LineComment = cm return nil } // Comment returns comment token instance func (n *SequenceEntryNode) GetComment() *CommentGroupNode { return n.LineComment } // MarshalYAML func (n *SequenceEntryNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } func (n *SequenceEntryNode) Read(p []byte) (int, error) { return readNode(p, n) } // SequenceEntry creates SequenceEntryNode instance. func SequenceEntry(start *token.Token, value Node, headComment *CommentGroupNode) *SequenceEntryNode { return &SequenceEntryNode{ BaseNode: &BaseNode{}, HeadComment: headComment, Start: start, Value: value, } } // SequenceMergeValue creates SequenceMergeValueNode instance. func SequenceMergeValue(values ...MapNode) *SequenceMergeValueNode { return &SequenceMergeValueNode{ values: values, } } // SequenceMergeValueNode is used to convert the Sequence node specified for the merge key into a MapNode format. type SequenceMergeValueNode struct { values []MapNode } // MapRange returns MapNodeIter instance. func (n *SequenceMergeValueNode) MapRange() *MapNodeIter { ret := &MapNodeIter{idx: startRangeIndex} for _, value := range n.values { iter := value.MapRange() ret.values = append(ret.values, iter.values...) } return ret } // AnchorNode type of anchor node type AnchorNode struct { *BaseNode Start *token.Token Name Node Value Node } func (n *AnchorNode) stringWithoutComment() string { return n.Value.String() } func (n *AnchorNode) SetName(name string) error { if n.Name == nil { return ErrInvalidAnchorName } s, ok := n.Name.(*StringNode) if !ok { return ErrInvalidAnchorName } s.Value = name return nil } // Read implements (io.Reader).Read func (n *AnchorNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns AnchorType func (n *AnchorNode) Type() NodeType { return AnchorType } // GetToken returns token instance func (n *AnchorNode) GetToken() *token.Token { return n.Start } func (n *AnchorNode) GetValue() any { return n.Value.GetToken().Value } // AddColumn add column number to child nodes recursively func (n *AnchorNode) AddColumn(col int) { n.Start.AddColumn(col) if n.Name != nil { n.Name.AddColumn(col) } if n.Value != nil { n.Value.AddColumn(col) } } // String anchor to text func (n *AnchorNode) String() string { anchor := "&" + n.Name.String() value := n.Value.String() if s, ok := n.Value.(*SequenceNode); ok && !s.IsFlowStyle { return fmt.Sprintf("%s\n%s", anchor, value) } else if m, ok := n.Value.(*MappingNode); ok && !m.IsFlowStyle { return fmt.Sprintf("%s\n%s", anchor, value) } if value == "" { // implicit null value. return anchor } return fmt.Sprintf("%s %s", anchor, value) } // MarshalYAML encodes to a YAML text func (n *AnchorNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *AnchorNode) IsMergeKey() bool { if n.Value == nil { return false } key, ok := n.Value.(MapKeyNode) if !ok { return false } return key.IsMergeKey() } // AliasNode type of alias node type AliasNode struct { *BaseNode Start *token.Token Value Node } func (n *AliasNode) stringWithoutComment() string { return n.Value.String() } func (n *AliasNode) SetName(name string) error { if n.Value == nil { return ErrInvalidAliasName } s, ok := n.Value.(*StringNode) if !ok { return ErrInvalidAliasName } s.Value = name return nil } // Read implements (io.Reader).Read func (n *AliasNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns AliasType func (n *AliasNode) Type() NodeType { return AliasType } // GetToken returns token instance func (n *AliasNode) GetToken() *token.Token { return n.Start } func (n *AliasNode) GetValue() any { return n.Value.GetToken().Value } // AddColumn add column number to child nodes recursively func (n *AliasNode) AddColumn(col int) { n.Start.AddColumn(col) if n.Value != nil { n.Value.AddColumn(col) } } // String alias to text func (n *AliasNode) String() string { return fmt.Sprintf("*%s", n.Value.String()) } // MarshalYAML encodes to a YAML text func (n *AliasNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *AliasNode) IsMergeKey() bool { return false } // DirectiveNode type of directive node type DirectiveNode struct { *BaseNode // Start is '%' token. Start *token.Token // Name is directive name e.g.) "YAML" or "TAG". Name Node // Values is directive values e.g.) "1.2" or "!!" and "tag:clarkevans.com,2002:app/". Values []Node } // Read implements (io.Reader).Read func (n *DirectiveNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns DirectiveType func (n *DirectiveNode) Type() NodeType { return DirectiveType } // GetToken returns token instance func (n *DirectiveNode) GetToken() *token.Token { return n.Start } // AddColumn add column number to child nodes recursively func (n *DirectiveNode) AddColumn(col int) { if n.Name != nil { n.Name.AddColumn(col) } for _, value := range n.Values { value.AddColumn(col) } } // String directive to text func (n *DirectiveNode) String() string { values := make([]string, 0, len(n.Values)) for _, val := range n.Values { values = append(values, val.String()) } return strings.Join(append([]string{"%" + n.Name.String()}, values...), " ") } // MarshalYAML encodes to a YAML text func (n *DirectiveNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // TagNode type of tag node type TagNode struct { *BaseNode Directive *DirectiveNode Start *token.Token Value Node } func (n *TagNode) GetValue() any { scalar, ok := n.Value.(ScalarNode) if !ok { return nil } return scalar.GetValue() } func (n *TagNode) stringWithoutComment() string { return n.Value.String() } // Read implements (io.Reader).Read func (n *TagNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns TagType func (n *TagNode) Type() NodeType { return TagType } // GetToken returns token instance func (n *TagNode) GetToken() *token.Token { return n.Start } // AddColumn add column number to child nodes recursively func (n *TagNode) AddColumn(col int) { n.Start.AddColumn(col) if n.Value != nil { n.Value.AddColumn(col) } } // String tag to text func (n *TagNode) String() string { value := n.Value.String() if s, ok := n.Value.(*SequenceNode); ok && !s.IsFlowStyle { return fmt.Sprintf("%s\n%s", n.Start.Value, value) } else if m, ok := n.Value.(*MappingNode); ok && !m.IsFlowStyle { return fmt.Sprintf("%s\n%s", n.Start.Value, value) } return fmt.Sprintf("%s %s", n.Start.Value, value) } // MarshalYAML encodes to a YAML text func (n *TagNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // IsMergeKey returns whether it is a MergeKey node. func (n *TagNode) IsMergeKey() bool { if n.Value == nil { return false } key, ok := n.Value.(MapKeyNode) if !ok { return false } return key.IsMergeKey() } func (n *TagNode) ArrayRange() *ArrayNodeIter { arr, ok := n.Value.(ArrayNode) if !ok { return nil } return arr.ArrayRange() } // CommentNode type of comment node type CommentNode struct { *BaseNode Token *token.Token } // Read implements (io.Reader).Read func (n *CommentNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns TagType func (n *CommentNode) Type() NodeType { return CommentType } // GetToken returns token instance func (n *CommentNode) GetToken() *token.Token { return n.Token } // AddColumn add column number to child nodes recursively func (n *CommentNode) AddColumn(col int) { if n.Token == nil { return } n.Token.AddColumn(col) } // String comment to text func (n *CommentNode) String() string { return fmt.Sprintf("#%s", n.Token.Value) } // MarshalYAML encodes to a YAML text func (n *CommentNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // CommentGroupNode type of comment node type CommentGroupNode struct { *BaseNode Comments []*CommentNode } // Read implements (io.Reader).Read func (n *CommentGroupNode) Read(p []byte) (int, error) { return readNode(p, n) } // Type returns TagType func (n *CommentGroupNode) Type() NodeType { return CommentType } // GetToken returns token instance func (n *CommentGroupNode) GetToken() *token.Token { if len(n.Comments) > 0 { return n.Comments[0].Token } return nil } // AddColumn add column number to child nodes recursively func (n *CommentGroupNode) AddColumn(col int) { for _, comment := range n.Comments { comment.AddColumn(col) } } // String comment to text func (n *CommentGroupNode) String() string { values := []string{} for _, comment := range n.Comments { values = append(values, comment.String()) } return strings.Join(values, "\n") } func (n *CommentGroupNode) StringWithSpace(col int) string { values := []string{} space := strings.Repeat(" ", col) for _, comment := range n.Comments { space := space if checkLineBreak(comment.Token) { space = fmt.Sprintf("%s%s", "\n", space) } values = append(values, space+comment.String()) } return strings.Join(values, "\n") } // MarshalYAML encodes to a YAML text func (n *CommentGroupNode) MarshalYAML() ([]byte, error) { return []byte(n.String()), nil } // Visitor has Visit method that is invokded for each node encountered by Walk. // If the result visitor w is not nil, Walk visits each of the children of node with the visitor w, // followed by a call of w.Visit(nil). type Visitor interface { Visit(Node) Visitor } // Walk traverses an AST in depth-first order: It starts by calling v.Visit(node); node must not be nil. // If the visitor w returned by v.Visit(node) is not nil, // Walk is invoked recursively with visitor w for each of the non-nil children of node, // followed by a call of w.Visit(nil). func Walk(v Visitor, node Node) { if v = v.Visit(node); v == nil { return } switch n := node.(type) { case *CommentNode: case *NullNode: walkComment(v, n.BaseNode) case *IntegerNode: walkComment(v, n.BaseNode) case *FloatNode: walkComment(v, n.BaseNode) case *StringNode: walkComment(v, n.BaseNode) case *MergeKeyNode: walkComment(v, n.BaseNode) case *BoolNode: walkComment(v, n.BaseNode) case *InfinityNode: walkComment(v, n.BaseNode) case *NanNode: walkComment(v, n.BaseNode) case *LiteralNode: walkComment(v, n.BaseNode) Walk(v, n.Value) case *DirectiveNode: walkComment(v, n.BaseNode) Walk(v, n.Name) for _, value := range n.Values { Walk(v, value) } case *TagNode: walkComment(v, n.BaseNode) Walk(v, n.Value) case *DocumentNode: walkComment(v, n.BaseNode) Walk(v, n.Body) case *MappingNode: walkComment(v, n.BaseNode) for _, value := range n.Values { Walk(v, value) } case *MappingKeyNode: walkComment(v, n.BaseNode) Walk(v, n.Value) case *MappingValueNode: walkComment(v, n.BaseNode) Walk(v, n.Key) Walk(v, n.Value) case *SequenceNode: walkComment(v, n.BaseNode) for _, value := range n.Values { Walk(v, value) } case *AnchorNode: walkComment(v, n.BaseNode) Walk(v, n.Name) Walk(v, n.Value) case *AliasNode: walkComment(v, n.BaseNode) Walk(v, n.Value) } } func walkComment(v Visitor, base *BaseNode) { if base == nil { return } if base.Comment == nil { return } Walk(v, base.Comment) } type filterWalker struct { typ NodeType results []Node } func (v *filterWalker) Visit(n Node) Visitor { if v.typ == n.Type() { v.results = append(v.results, n) } return v } type parentFinder struct { target Node } func (f *parentFinder) walk(parent, node Node) Node { if f.target == node { return parent } switch n := node.(type) { case *CommentNode: return nil case *NullNode: return nil case *IntegerNode: return nil case *FloatNode: return nil case *StringNode: return nil case *MergeKeyNode: return nil case *BoolNode: return nil case *InfinityNode: return nil case *NanNode: return nil case *LiteralNode: return f.walk(node, n.Value) case *DirectiveNode: if found := f.walk(node, n.Name); found != nil { return found } for _, value := range n.Values { if found := f.walk(node, value); found != nil { return found } } case *TagNode: return f.walk(node, n.Value) case *DocumentNode: return f.walk(node, n.Body) case *MappingNode: for _, value := range n.Values { if found := f.walk(node, value); found != nil { return found } } case *MappingKeyNode: return f.walk(node, n.Value) case *MappingValueNode: if found := f.walk(node, n.Key); found != nil { return found } return f.walk(node, n.Value) case *SequenceNode: for _, value := range n.Values { if found := f.walk(node, value); found != nil { return found } } case *AnchorNode: if found := f.walk(node, n.Name); found != nil { return found } return f.walk(node, n.Value) case *AliasNode: return f.walk(node, n.Value) } return nil } // Parent get parent node from child node. func Parent(root, child Node) Node { finder := &parentFinder{target: child} return finder.walk(root, root) } // Filter returns a list of nodes that match the given type. func Filter(typ NodeType, node Node) []Node { walker := &filterWalker{typ: typ} Walk(walker, node) return walker.results } // FilterFile returns a list of nodes that match the given type. func FilterFile(typ NodeType, file *File) []Node { results := []Node{} for _, doc := range file.Docs { walker := &filterWalker{typ: typ} Walk(walker, doc) results = append(results, walker.results...) } return results } type ErrInvalidMergeType struct { dst Node src Node } func (e *ErrInvalidMergeType) Error() string { return fmt.Sprintf("cannot merge %s into %s", e.src.Type(), e.dst.Type()) } // Merge merge document, map, sequence node. func Merge(dst Node, src Node) error { if doc, ok := src.(*DocumentNode); ok { src = doc.Body } err := &ErrInvalidMergeType{dst: dst, src: src} switch dst.Type() { case DocumentType: node, _ := dst.(*DocumentNode) return Merge(node.Body, src) case MappingType: node, _ := dst.(*MappingNode) target, ok := src.(*MappingNode) if !ok { return err } node.Merge(target) return nil case SequenceType: node, _ := dst.(*SequenceNode) target, ok := src.(*SequenceNode) if !ok { return err } node.Merge(target) return nil } return err } goccy-go-yaml-52dacb8/ast/ast_test.go000066400000000000000000000015311501576637100176320ustar00rootroot00000000000000package ast import ( "testing" "github.com/goccy/go-yaml/token" ) func TestEscapeSingleQuote(t *testing.T) { expected := `'Victor''s victory'` got := escapeSingleQuote("Victor's victory") if got != expected { t.Fatalf("expected:%s\ngot:%s", expected, got) } } func TestReadNode(t *testing.T) { t.Run("utf-8", func(t *testing.T) { value := "éɛทᛞ⠻チ▓🦄" node := &StringNode{ BaseNode: &BaseNode{}, Token: &token.Token{}, Value: value, } expectedSize := len(value) gotBuffer := make([]byte, expectedSize) expectedBuffer := []byte(value) gotSize, _ := readNode(gotBuffer, node) if gotSize != expectedSize { t.Fatalf("expected size:%d\ngot:%d", expectedSize, gotSize) } if string(gotBuffer) != string(expectedBuffer) { t.Fatalf("expected buffer:%s\ngot:%s", expectedBuffer, gotBuffer) } }) } goccy-go-yaml-52dacb8/benchmarks/000077500000000000000000000000001501576637100170035ustar00rootroot00000000000000goccy-go-yaml-52dacb8/benchmarks/benchmark_test.go000066400000000000000000000016571501576637100223340ustar00rootroot00000000000000package benchmarks import ( "testing" "github.com/goccy/go-yaml" goyaml2 "gopkg.in/yaml.v2" goyaml3 "gopkg.in/yaml.v3" ) func Benchmark(b *testing.B) { const src = `--- id: 1 message: Hello, World verified: true elements: - one - 0.02 - null - -inf ` type T struct { ID int `yaml:"id"` Message string `yaml:"message"` Verified bool `yaml:"verified,omitempty"` } b.Run("gopkg.in/yaml.v2", func(b *testing.B) { var t T for i := 0; i < b.N; i++ { if err := goyaml2.Unmarshal([]byte(src), &t); err != nil { b.Fatal(err) } } }) b.Run("gopkg.in/yaml.v3", func(b *testing.B) { var t T for i := 0; i < b.N; i++ { if err := goyaml3.Unmarshal([]byte(src), &t); err != nil { b.Fatal(err) } } }) b.Run("github.com/goccy/go-yaml", func(b *testing.B) { var t T for i := 0; i < b.N; i++ { if err := yaml.Unmarshal([]byte(src), &t); err != nil { b.Fatal(err) } } }) } goccy-go-yaml-52dacb8/benchmarks/go.mod000066400000000000000000000003321501576637100201070ustar00rootroot00000000000000module github.com/goccy/go-yaml/benchmarks go 1.21.0 replace github.com/goccy/go-yaml => .. require ( github.com/goccy/go-yaml v0.0.0-00010101000000-000000000000 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 ) goccy-go-yaml-52dacb8/benchmarks/go.sum000066400000000000000000000007771501576637100201510ustar00rootroot00000000000000gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= goccy-go-yaml-52dacb8/cmd/000077500000000000000000000000001501576637100154315ustar00rootroot00000000000000goccy-go-yaml-52dacb8/cmd/ycat/000077500000000000000000000000001501576637100163715ustar00rootroot00000000000000goccy-go-yaml-52dacb8/cmd/ycat/go.mod000066400000000000000000000005241501576637100175000ustar00rootroot00000000000000module github.com/goccy/go-yaml/cmd/ycat go 1.21.0 require ( github.com/fatih/color v1.18.0 github.com/goccy/go-yaml v0.0.0-00010101000000-000000000000 github.com/mattn/go-colorable v0.1.13 ) require ( github.com/mattn/go-isatty v0.0.20 // indirect golang.org/x/sys v0.26.0 // indirect ) replace github.com/goccy/go-yaml => ../../ goccy-go-yaml-52dacb8/cmd/ycat/go.sum000066400000000000000000000047431501576637100175340ustar00rootroot00000000000000github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= goccy-go-yaml-52dacb8/cmd/ycat/ycat.go000066400000000000000000000036741501576637100176720ustar00rootroot00000000000000package main import ( "errors" "fmt" "os" "github.com/fatih/color" "github.com/mattn/go-colorable" "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/lexer" "github.com/goccy/go-yaml/printer" ) const escape = "\x1b" func format(attr color.Attribute) string { return fmt.Sprintf("%s[%dm", escape, attr) } func _main(args []string) error { if len(args) < 2 { return errors.New("ycat: usage: ycat file.yml") } filename := args[1] bytes, err := os.ReadFile(filename) if err != nil { return err } tokens := lexer.Tokenize(string(bytes)) var p printer.Printer p.LineNumber = true p.LineNumberFormat = func(num int) string { fn := color.New(color.Bold, color.FgHiWhite).SprintFunc() return fn(fmt.Sprintf("%2d | ", num)) } p.Bool = func() *printer.Property { return &printer.Property{ Prefix: format(color.FgHiMagenta), Suffix: format(color.Reset), } } p.Number = func() *printer.Property { return &printer.Property{ Prefix: format(color.FgHiMagenta), Suffix: format(color.Reset), } } p.MapKey = func() *printer.Property { return &printer.Property{ Prefix: format(color.FgHiCyan), Suffix: format(color.Reset), } } p.Anchor = func() *printer.Property { return &printer.Property{ Prefix: format(color.FgHiYellow), Suffix: format(color.Reset), } } p.Alias = func() *printer.Property { return &printer.Property{ Prefix: format(color.FgHiYellow), Suffix: format(color.Reset), } } p.String = func() *printer.Property { return &printer.Property{ Prefix: format(color.FgHiGreen), Suffix: format(color.Reset), } } p.Comment = func() *printer.Property { return &printer.Property{ Prefix: format(color.FgHiBlack), Suffix: format(color.Reset), } } writer := colorable.NewColorableStdout() _, _ = writer.Write([]byte(p.PrintTokens(tokens) + "\n")) return nil } func main() { if err := _main(os.Args); err != nil { fmt.Printf("%v\n", yaml.FormatError(err, true, true)) } } goccy-go-yaml-52dacb8/context.go000066400000000000000000000013371501576637100167050ustar00rootroot00000000000000package yaml import "context" type ( ctxMergeKey struct{} ctxAnchorKey struct{} ) func withMerge(ctx context.Context) context.Context { return context.WithValue(ctx, ctxMergeKey{}, true) } func isMerge(ctx context.Context) bool { v, ok := ctx.Value(ctxMergeKey{}).(bool) if !ok { return false } return v } func withAnchor(ctx context.Context, name string) context.Context { anchorMap := getAnchorMap(ctx) if anchorMap == nil { anchorMap = make(map[string]struct{}) } anchorMap[name] = struct{}{} return context.WithValue(ctx, ctxAnchorKey{}, anchorMap) } func getAnchorMap(ctx context.Context) map[string]struct{} { v, ok := ctx.Value(ctxAnchorKey{}).(map[string]struct{}) if !ok { return nil } return v } goccy-go-yaml-52dacb8/decode.go000066400000000000000000001434031501576637100164450ustar00rootroot00000000000000package yaml import ( "bytes" "context" "encoding" "encoding/base64" "fmt" "io" "maps" "math" "os" "path/filepath" "reflect" "sort" "strconv" "strings" "time" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" "github.com/goccy/go-yaml/internal/format" "github.com/goccy/go-yaml/parser" "github.com/goccy/go-yaml/token" ) // Decoder reads and decodes YAML values from an input stream. type Decoder struct { reader io.Reader referenceReaders []io.Reader anchorNodeMap map[string]ast.Node anchorValueMap map[string]reflect.Value customUnmarshalerMap map[reflect.Type]func(context.Context, interface{}, []byte) error commentMaps []CommentMap toCommentMap CommentMap opts []DecodeOption referenceFiles []string referenceDirs []string isRecursiveDir bool isResolvedReference bool validator StructValidator disallowUnknownField bool allowDuplicateMapKey bool useOrderedMap bool useJSONUnmarshaler bool parsedFile *ast.File streamIndex int decodeDepth int } // NewDecoder returns a new decoder that reads from r. func NewDecoder(r io.Reader, opts ...DecodeOption) *Decoder { return &Decoder{ reader: r, anchorNodeMap: map[string]ast.Node{}, anchorValueMap: map[string]reflect.Value{}, customUnmarshalerMap: map[reflect.Type]func(context.Context, interface{}, []byte) error{}, opts: opts, referenceReaders: []io.Reader{}, referenceFiles: []string{}, referenceDirs: []string{}, isRecursiveDir: false, isResolvedReference: false, disallowUnknownField: false, allowDuplicateMapKey: false, useOrderedMap: false, } } const maxDecodeDepth = 10000 func (d *Decoder) stepIn() { d.decodeDepth++ } func (d *Decoder) stepOut() { d.decodeDepth-- } func (d *Decoder) isExceededMaxDepth() bool { return d.decodeDepth > maxDecodeDepth } func (d *Decoder) castToFloat(v interface{}) interface{} { switch vv := v.(type) { case int: return float64(vv) case int8: return float64(vv) case int16: return float64(vv) case int32: return float64(vv) case int64: return float64(vv) case uint: return float64(vv) case uint8: return float64(vv) case uint16: return float64(vv) case uint32: return float64(vv) case uint64: return float64(vv) case float32: return float64(vv) case float64: return vv case string: // if error occurred, return zero value f, _ := strconv.ParseFloat(vv, 64) return f } return 0 } func (d *Decoder) mapKeyNodeToString(ctx context.Context, node ast.MapKeyNode) (string, error) { key, err := d.nodeToValue(ctx, node) if err != nil { return "", err } if key == nil { return "null", nil } if k, ok := key.(string); ok { return k, nil } return fmt.Sprint(key), nil } func (d *Decoder) setToMapValue(ctx context.Context, node ast.Node, m map[string]interface{}) error { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return ErrExceededMaxDepth } d.setPathToCommentMap(node) switch n := node.(type) { case *ast.MappingValueNode: if n.Key.IsMergeKey() { value, err := d.getMapNode(n.Value, true) if err != nil { return err } iter := value.MapRange() for iter.Next() { if err := d.setToMapValue(ctx, iter.KeyValue(), m); err != nil { return err } } } else { key, err := d.mapKeyNodeToString(ctx, n.Key) if err != nil { return err } v, err := d.nodeToValue(ctx, n.Value) if err != nil { return err } m[key] = v } case *ast.MappingNode: for _, value := range n.Values { if err := d.setToMapValue(ctx, value, m); err != nil { return err } } case *ast.AnchorNode: anchorName := n.Name.GetToken().Value d.anchorNodeMap[anchorName] = n.Value } return nil } func (d *Decoder) setToOrderedMapValue(ctx context.Context, node ast.Node, m *MapSlice) error { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return ErrExceededMaxDepth } d.setPathToCommentMap(node) switch n := node.(type) { case *ast.MappingValueNode: if n.Key.IsMergeKey() { value, err := d.getMapNode(n.Value, true) if err != nil { return err } iter := value.MapRange() for iter.Next() { if err := d.setToOrderedMapValue(ctx, iter.KeyValue(), m); err != nil { return err } } } else { key, err := d.mapKeyNodeToString(ctx, n.Key) if err != nil { return err } value, err := d.nodeToValue(ctx, n.Value) if err != nil { return err } *m = append(*m, MapItem{Key: key, Value: value}) } case *ast.MappingNode: for _, value := range n.Values { if err := d.setToOrderedMapValue(ctx, value, m); err != nil { return err } } } return nil } func (d *Decoder) setPathToCommentMap(node ast.Node) { if node == nil { return } if d.toCommentMap == nil { return } d.addHeadOrLineCommentToMap(node) d.addFootCommentToMap(node) } func (d *Decoder) addHeadOrLineCommentToMap(node ast.Node) { sequence, ok := node.(*ast.SequenceNode) if ok { d.addSequenceNodeCommentToMap(sequence) return } commentGroup := node.GetComment() if commentGroup == nil { return } texts := []string{} targetLine := node.GetToken().Position.Line minCommentLine := math.MaxInt for _, comment := range commentGroup.Comments { if minCommentLine > comment.Token.Position.Line { minCommentLine = comment.Token.Position.Line } texts = append(texts, comment.Token.Value) } if len(texts) == 0 { return } commentPath := node.GetPath() if minCommentLine < targetLine { switch n := node.(type) { case *ast.MappingNode: if len(n.Values) != 0 { commentPath = n.Values[0].Key.GetPath() } case *ast.MappingValueNode: commentPath = n.Key.GetPath() } d.addCommentToMap(commentPath, HeadComment(texts...)) } else { d.addCommentToMap(commentPath, LineComment(texts[0])) } } func (d *Decoder) addSequenceNodeCommentToMap(node *ast.SequenceNode) { if len(node.ValueHeadComments) != 0 { for idx, headComment := range node.ValueHeadComments { if headComment == nil { continue } texts := make([]string, 0, len(headComment.Comments)) for _, comment := range headComment.Comments { texts = append(texts, comment.Token.Value) } if len(texts) != 0 { d.addCommentToMap(node.Values[idx].GetPath(), HeadComment(texts...)) } } } firstElemHeadComment := node.GetComment() if firstElemHeadComment != nil { texts := make([]string, 0, len(firstElemHeadComment.Comments)) for _, comment := range firstElemHeadComment.Comments { texts = append(texts, comment.Token.Value) } if len(texts) != 0 { d.addCommentToMap(node.Values[0].GetPath(), HeadComment(texts...)) } } } func (d *Decoder) addFootCommentToMap(node ast.Node) { var ( footComment *ast.CommentGroupNode footCommentPath = node.GetPath() ) switch n := node.(type) { case *ast.SequenceNode: footComment = n.FootComment if n.FootComment != nil { footCommentPath = n.FootComment.GetPath() } case *ast.MappingNode: footComment = n.FootComment if n.FootComment != nil { footCommentPath = n.FootComment.GetPath() } case *ast.MappingValueNode: footComment = n.FootComment if n.FootComment != nil { footCommentPath = n.FootComment.GetPath() } } if footComment == nil { return } var texts []string for _, comment := range footComment.Comments { texts = append(texts, comment.Token.Value) } if len(texts) != 0 { d.addCommentToMap(footCommentPath, FootComment(texts...)) } } func (d *Decoder) addCommentToMap(path string, comment *Comment) { for _, c := range d.toCommentMap[path] { if c.Position == comment.Position { // already added same comment return } } d.toCommentMap[path] = append(d.toCommentMap[path], comment) sort.Slice(d.toCommentMap[path], func(i, j int) bool { return d.toCommentMap[path][i].Position < d.toCommentMap[path][j].Position }) } func (d *Decoder) nodeToValue(ctx context.Context, node ast.Node) (any, error) { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return nil, ErrExceededMaxDepth } d.setPathToCommentMap(node) switch n := node.(type) { case *ast.NullNode: return nil, nil case *ast.StringNode: return n.GetValue(), nil case *ast.IntegerNode: return n.GetValue(), nil case *ast.FloatNode: return n.GetValue(), nil case *ast.BoolNode: return n.GetValue(), nil case *ast.InfinityNode: return n.GetValue(), nil case *ast.NanNode: return n.GetValue(), nil case *ast.TagNode: if n.Directive != nil { v, err := d.nodeToValue(ctx, n.Value) if err != nil { return nil, err } if v == nil { return "", nil } return fmt.Sprint(v), nil } switch token.ReservedTagKeyword(n.Start.Value) { case token.TimestampTag: t, _ := d.castToTime(ctx, n.Value) return t, nil case token.IntegerTag: v, err := d.nodeToValue(ctx, n.Value) if err != nil { return nil, err } i, _ := strconv.Atoi(fmt.Sprint(v)) return i, nil case token.FloatTag: v, err := d.nodeToValue(ctx, n.Value) if err != nil { return nil, err } return d.castToFloat(v), nil case token.NullTag: return nil, nil case token.BinaryTag: v, err := d.nodeToValue(ctx, n.Value) if err != nil { return nil, err } str, ok := v.(string) if !ok { return nil, errors.ErrSyntax( fmt.Sprintf("cannot convert %q to string", fmt.Sprint(v)), n.Value.GetToken(), ) } b, _ := base64.StdEncoding.DecodeString(str) return b, nil case token.BooleanTag: v, err := d.nodeToValue(ctx, n.Value) if err != nil { return nil, err } str := strings.ToLower(fmt.Sprint(v)) b, err := strconv.ParseBool(str) if err == nil { return b, nil } switch str { case "yes": return true, nil case "no": return false, nil } return nil, errors.ErrSyntax(fmt.Sprintf("cannot convert %q to boolean", fmt.Sprint(v)), n.Value.GetToken()) case token.StringTag: v, err := d.nodeToValue(ctx, n.Value) if err != nil { return nil, err } if v == nil { return "", nil } return fmt.Sprint(v), nil case token.MappingTag: return d.nodeToValue(ctx, n.Value) default: return d.nodeToValue(ctx, n.Value) } case *ast.AnchorNode: anchorName := n.Name.GetToken().Value // To handle the case where alias is processed recursively, the result of alias can be set to nil in advance. d.anchorNodeMap[anchorName] = nil anchorValue, err := d.nodeToValue(withAnchor(ctx, anchorName), n.Value) if err != nil { delete(d.anchorNodeMap, anchorName) return nil, err } d.anchorNodeMap[anchorName] = n.Value d.anchorValueMap[anchorName] = reflect.ValueOf(anchorValue) return anchorValue, nil case *ast.AliasNode: text := n.Value.String() if _, exists := getAnchorMap(ctx)[text]; exists { // self recursion. return nil, nil } if v, exists := d.anchorValueMap[text]; exists { if !v.IsValid() { return nil, nil } return v.Interface(), nil } aliasName := n.Value.GetToken().Value return nil, errors.ErrSyntax(fmt.Sprintf("could not find alias %q", aliasName), n.Value.GetToken()) case *ast.LiteralNode: return n.Value.GetValue(), nil case *ast.MappingKeyNode: return d.nodeToValue(ctx, n.Value) case *ast.MappingValueNode: if n.Key.IsMergeKey() { value, err := d.getMapNode(n.Value, true) if err != nil { return nil, err } iter := value.MapRange() if d.useOrderedMap { m := MapSlice{} for iter.Next() { if err := d.setToOrderedMapValue(ctx, iter.KeyValue(), &m); err != nil { return nil, err } } return m, nil } m := make(map[string]any) for iter.Next() { if err := d.setToMapValue(ctx, iter.KeyValue(), m); err != nil { return nil, err } } return m, nil } key, err := d.mapKeyNodeToString(ctx, n.Key) if err != nil { return nil, err } if d.useOrderedMap { v, err := d.nodeToValue(ctx, n.Value) if err != nil { return nil, err } return MapSlice{{Key: key, Value: v}}, nil } v, err := d.nodeToValue(ctx, n.Value) if err != nil { return nil, err } return map[string]interface{}{key: v}, nil case *ast.MappingNode: if d.useOrderedMap { m := make(MapSlice, 0, len(n.Values)) for _, value := range n.Values { if err := d.setToOrderedMapValue(ctx, value, &m); err != nil { return nil, err } } return m, nil } m := make(map[string]interface{}, len(n.Values)) for _, value := range n.Values { if err := d.setToMapValue(ctx, value, m); err != nil { return nil, err } } return m, nil case *ast.SequenceNode: v := make([]interface{}, 0, len(n.Values)) for _, value := range n.Values { vv, err := d.nodeToValue(ctx, value) if err != nil { return nil, err } v = append(v, vv) } return v, nil } return nil, nil } func (d *Decoder) getMapNode(node ast.Node, isMerge bool) (ast.MapNode, error) { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return nil, ErrExceededMaxDepth } switch n := node.(type) { case ast.MapNode: return n, nil case *ast.AnchorNode: anchorName := n.Name.GetToken().Value d.anchorNodeMap[anchorName] = n.Value return d.getMapNode(n.Value, isMerge) case *ast.AliasNode: aliasName := n.Value.GetToken().Value node := d.anchorNodeMap[aliasName] if node == nil { return nil, fmt.Errorf("cannot find anchor by alias name %s", aliasName) } return d.getMapNode(node, isMerge) case *ast.SequenceNode: if !isMerge { return nil, errors.ErrUnexpectedNodeType(node.Type(), ast.MappingType, node.GetToken()) } var mapNodes []ast.MapNode for _, value := range n.Values { mapNode, err := d.getMapNode(value, false) if err != nil { return nil, err } mapNodes = append(mapNodes, mapNode) } return ast.SequenceMergeValue(mapNodes...), nil } return nil, errors.ErrUnexpectedNodeType(node.Type(), ast.MappingType, node.GetToken()) } func (d *Decoder) getArrayNode(node ast.Node) (ast.ArrayNode, error) { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return nil, ErrExceededMaxDepth } if _, ok := node.(*ast.NullNode); ok { return nil, nil } if anchor, ok := node.(*ast.AnchorNode); ok { arrayNode, ok := anchor.Value.(ast.ArrayNode) if ok { return arrayNode, nil } return nil, errors.ErrUnexpectedNodeType(anchor.Value.Type(), ast.SequenceType, node.GetToken()) } if alias, ok := node.(*ast.AliasNode); ok { aliasName := alias.Value.GetToken().Value node := d.anchorNodeMap[aliasName] if node == nil { return nil, fmt.Errorf("cannot find anchor by alias name %s", aliasName) } arrayNode, ok := node.(ast.ArrayNode) if ok { return arrayNode, nil } return nil, errors.ErrUnexpectedNodeType(node.Type(), ast.SequenceType, node.GetToken()) } arrayNode, ok := node.(ast.ArrayNode) if !ok { return nil, errors.ErrUnexpectedNodeType(node.Type(), ast.SequenceType, node.GetToken()) } return arrayNode, nil } func (d *Decoder) convertValue(v reflect.Value, typ reflect.Type, src ast.Node) (reflect.Value, error) { if typ.Kind() != reflect.String { if !v.Type().ConvertibleTo(typ) { // Special case for "strings -> floats" aka scientific notation // If the destination type is a float and the source type is a string, check if we can // use strconv.ParseFloat to convert the string to a float. if (typ.Kind() == reflect.Float32 || typ.Kind() == reflect.Float64) && v.Type().Kind() == reflect.String { if f, err := strconv.ParseFloat(v.String(), 64); err == nil { if typ.Kind() == reflect.Float32 { return reflect.ValueOf(float32(f)), nil } else if typ.Kind() == reflect.Float64 { return reflect.ValueOf(f), nil } // else, fall through to the error below } } return reflect.Zero(typ), errors.ErrTypeMismatch(typ, v.Type(), src.GetToken()) } return v.Convert(typ), nil } // cast value to string var strVal string switch v.Type().Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: strVal = strconv.FormatInt(v.Int(), 10) case reflect.Float32, reflect.Float64: strVal = fmt.Sprint(v.Float()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: strVal = strconv.FormatUint(v.Uint(), 10) case reflect.Bool: strVal = strconv.FormatBool(v.Bool()) default: if !v.Type().ConvertibleTo(typ) { return reflect.Zero(typ), errors.ErrTypeMismatch(typ, v.Type(), src.GetToken()) } return v.Convert(typ), nil } val := reflect.ValueOf(strVal) if val.Type() != typ { // Handle named types, e.g., `type MyString string` val = val.Convert(typ) } return val, nil } func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[string]ast.Node) error { if structType.Kind() == reflect.Ptr { structType = structType.Elem() } structFieldMap, err := structFieldMap(structType) if err != nil { return err } for j := 0; j < structType.NumField(); j++ { field := structType.Field(j) if isIgnoredStructField(field) { continue } structField, exists := structFieldMap[field.Name] if !exists { continue } if structField.IsInline { _ = d.deleteStructKeys(field.Type, unknownFields) } else { delete(unknownFields, structField.RenderName) } } return nil } func (d *Decoder) unmarshalableDocument(node ast.Node) ([]byte, error) { doc := format.FormatNodeWithResolvedAlias(node, d.anchorNodeMap) return []byte(doc), nil } func (d *Decoder) unmarshalableText(node ast.Node) ([]byte, bool) { doc := format.FormatNodeWithResolvedAlias(node, d.anchorNodeMap) var v string if err := Unmarshal([]byte(doc), &v); err != nil { return nil, false } return []byte(v), true } type jsonUnmarshaler interface { UnmarshalJSON([]byte) error } func (d *Decoder) existsTypeInCustomUnmarshalerMap(t reflect.Type) bool { if _, exists := d.customUnmarshalerMap[t]; exists { return true } globalCustomUnmarshalerMu.Lock() defer globalCustomUnmarshalerMu.Unlock() if _, exists := globalCustomUnmarshalerMap[t]; exists { return true } return false } func (d *Decoder) unmarshalerFromCustomUnmarshalerMap(t reflect.Type) (func(context.Context, interface{}, []byte) error, bool) { if unmarshaler, exists := d.customUnmarshalerMap[t]; exists { return unmarshaler, exists } globalCustomUnmarshalerMu.Lock() defer globalCustomUnmarshalerMu.Unlock() if unmarshaler, exists := globalCustomUnmarshalerMap[t]; exists { return unmarshaler, exists } return nil, false } func (d *Decoder) canDecodeByUnmarshaler(dst reflect.Value) bool { ptrValue := dst.Addr() if d.existsTypeInCustomUnmarshalerMap(ptrValue.Type()) { return true } iface := ptrValue.Interface() switch iface.(type) { case BytesUnmarshalerContext, BytesUnmarshaler, InterfaceUnmarshalerContext, InterfaceUnmarshaler, NodeUnmarshaler, NodeUnmarshalerContext, *time.Time, *time.Duration, encoding.TextUnmarshaler: return true case jsonUnmarshaler: return d.useJSONUnmarshaler } return false } func (d *Decoder) decodeByUnmarshaler(ctx context.Context, dst reflect.Value, src ast.Node) error { ptrValue := dst.Addr() if unmarshaler, exists := d.unmarshalerFromCustomUnmarshalerMap(ptrValue.Type()); exists { b, err := d.unmarshalableDocument(src) if err != nil { return err } if err := unmarshaler(ctx, ptrValue.Interface(), b); err != nil { return err } return nil } iface := ptrValue.Interface() if unmarshaler, ok := iface.(BytesUnmarshalerContext); ok { b, err := d.unmarshalableDocument(src) if err != nil { return err } if err := unmarshaler.UnmarshalYAML(ctx, b); err != nil { return err } return nil } if unmarshaler, ok := iface.(BytesUnmarshaler); ok { b, err := d.unmarshalableDocument(src) if err != nil { return err } if err := unmarshaler.UnmarshalYAML(b); err != nil { return err } return nil } if unmarshaler, ok := iface.(InterfaceUnmarshalerContext); ok { if err := unmarshaler.UnmarshalYAML(ctx, func(v interface{}) error { rv := reflect.ValueOf(v) if rv.Type().Kind() != reflect.Ptr { return ErrDecodeRequiredPointerType } if err := d.decodeValue(ctx, rv.Elem(), src); err != nil { return err } return nil }); err != nil { return err } return nil } if unmarshaler, ok := iface.(InterfaceUnmarshaler); ok { if err := unmarshaler.UnmarshalYAML(func(v interface{}) error { rv := reflect.ValueOf(v) if rv.Type().Kind() != reflect.Ptr { return ErrDecodeRequiredPointerType } if err := d.decodeValue(ctx, rv.Elem(), src); err != nil { return err } return nil }); err != nil { return err } return nil } if unmarshaler, ok := iface.(NodeUnmarshaler); ok { if err := unmarshaler.UnmarshalYAML(src); err != nil { return err } return nil } if unmarshaler, ok := iface.(NodeUnmarshalerContext); ok { if err := unmarshaler.UnmarshalYAML(ctx, src); err != nil { return err } return nil } if _, ok := iface.(*time.Time); ok { return d.decodeTime(ctx, dst, src) } if _, ok := iface.(*time.Duration); ok { return d.decodeDuration(ctx, dst, src) } if unmarshaler, isText := iface.(encoding.TextUnmarshaler); isText { b, ok := d.unmarshalableText(src) if ok { if err := unmarshaler.UnmarshalText(b); err != nil { return err } return nil } } if d.useJSONUnmarshaler { if unmarshaler, ok := iface.(jsonUnmarshaler); ok { b, err := d.unmarshalableDocument(src) if err != nil { return err } jsonBytes, err := YAMLToJSON(b) if err != nil { return err } jsonBytes = bytes.TrimRight(jsonBytes, "\n") if err := unmarshaler.UnmarshalJSON(jsonBytes); err != nil { return err } return nil } } return errors.New("does not implemented Unmarshaler") } var ( astNodeType = reflect.TypeOf((*ast.Node)(nil)).Elem() ) func (d *Decoder) decodeValue(ctx context.Context, dst reflect.Value, src ast.Node) error { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return ErrExceededMaxDepth } if !dst.IsValid() { return nil } if src.Type() == ast.AnchorType { anchor, _ := src.(*ast.AnchorNode) anchorName := anchor.Name.GetToken().Value if err := d.decodeValue(withAnchor(ctx, anchorName), dst, anchor.Value); err != nil { return err } d.anchorValueMap[anchorName] = dst return nil } if d.canDecodeByUnmarshaler(dst) { if err := d.decodeByUnmarshaler(ctx, dst, src); err != nil { return err } return nil } valueType := dst.Type() switch valueType.Kind() { case reflect.Ptr: if dst.IsNil() { return nil } if src.Type() == ast.NullType { // set nil value to pointer dst.Set(reflect.Zero(valueType)) return nil } v := d.createDecodableValue(dst.Type()) if err := d.decodeValue(ctx, v, src); err != nil { return err } castedValue, err := d.castToAssignableValue(v, dst.Type(), src) if err != nil { return err } dst.Set(castedValue) case reflect.Interface: if dst.Type() == astNodeType { dst.Set(reflect.ValueOf(src)) return nil } srcVal, err := d.nodeToValue(ctx, src) if err != nil { return err } v := reflect.ValueOf(srcVal) if v.IsValid() { dst.Set(v) } else { dst.Set(reflect.Zero(valueType)) } case reflect.Map: return d.decodeMap(ctx, dst, src) case reflect.Array: return d.decodeArray(ctx, dst, src) case reflect.Slice: if mapSlice, ok := dst.Addr().Interface().(*MapSlice); ok { return d.decodeMapSlice(ctx, mapSlice, src) } return d.decodeSlice(ctx, dst, src) case reflect.Struct: if mapItem, ok := dst.Addr().Interface().(*MapItem); ok { return d.decodeMapItem(ctx, mapItem, src) } return d.decodeStruct(ctx, dst, src) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: v, err := d.nodeToValue(ctx, src) if err != nil { return err } switch vv := v.(type) { case int64: if !dst.OverflowInt(vv) { dst.SetInt(vv) return nil } case uint64: if vv <= math.MaxInt64 && !dst.OverflowInt(int64(vv)) { dst.SetInt(int64(vv)) return nil } case float64: if vv <= math.MaxInt64 && !dst.OverflowInt(int64(vv)) { dst.SetInt(int64(vv)) return nil } case string: // handle scientific notation if i, err := strconv.ParseFloat(vv, 64); err == nil { if 0 <= i && i <= math.MaxUint64 && !dst.OverflowInt(int64(i)) { dst.SetInt(int64(i)) return nil } } else { // couldn't be parsed as float return errors.ErrTypeMismatch(valueType, reflect.TypeOf(v), src.GetToken()) } default: return errors.ErrTypeMismatch(valueType, reflect.TypeOf(v), src.GetToken()) } return errors.ErrOverflow(valueType, fmt.Sprint(v), src.GetToken()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: v, err := d.nodeToValue(ctx, src) if err != nil { return err } switch vv := v.(type) { case int64: if 0 <= vv && !dst.OverflowUint(uint64(vv)) { dst.SetUint(uint64(vv)) return nil } case uint64: if !dst.OverflowUint(vv) { dst.SetUint(vv) return nil } case float64: if 0 <= vv && vv <= math.MaxUint64 && !dst.OverflowUint(uint64(vv)) { dst.SetUint(uint64(vv)) return nil } case string: // handle scientific notation if i, err := strconv.ParseFloat(vv, 64); err == nil { if 0 <= i && i <= math.MaxUint64 && !dst.OverflowUint(uint64(i)) { dst.SetUint(uint64(i)) return nil } } else { // couldn't be parsed as float return errors.ErrTypeMismatch(valueType, reflect.TypeOf(v), src.GetToken()) } default: return errors.ErrTypeMismatch(valueType, reflect.TypeOf(v), src.GetToken()) } return errors.ErrOverflow(valueType, fmt.Sprint(v), src.GetToken()) } srcVal, err := d.nodeToValue(ctx, src) if err != nil { return err } v := reflect.ValueOf(srcVal) if v.IsValid() { convertedValue, err := d.convertValue(v, dst.Type(), src) if err != nil { return err } dst.Set(convertedValue) } return nil } func (d *Decoder) createDecodableValue(typ reflect.Type) reflect.Value { for { if typ.Kind() == reflect.Ptr { typ = typ.Elem() continue } break } return reflect.New(typ).Elem() } func (d *Decoder) castToAssignableValue(value reflect.Value, target reflect.Type, src ast.Node) (reflect.Value, error) { if target.Kind() != reflect.Ptr { if !value.Type().AssignableTo(target) { return reflect.Value{}, errors.ErrTypeMismatch(target, value.Type(), src.GetToken()) } return value, nil } const maxAddrCount = 5 for i := 0; i < maxAddrCount; i++ { if value.Type().AssignableTo(target) { break } if !value.CanAddr() { break } value = value.Addr() } if !value.Type().AssignableTo(target) { return reflect.Value{}, errors.ErrTypeMismatch(target, value.Type(), src.GetToken()) } return value, nil } func (d *Decoder) createDecodedNewValue( ctx context.Context, typ reflect.Type, defaultVal reflect.Value, node ast.Node, ) (reflect.Value, error) { if node.Type() == ast.AliasType { aliasName := node.(*ast.AliasNode).Value.GetToken().Value value := d.anchorValueMap[aliasName] if value.IsValid() { v, err := d.castToAssignableValue(value, typ, node) if err == nil { return v, nil } } anchor, exists := d.anchorNodeMap[aliasName] if exists { node = anchor } } var newValue reflect.Value if node.Type() == ast.NullType { newValue = reflect.New(typ).Elem() } else { newValue = d.createDecodableValue(typ) } for defaultVal.Kind() == reflect.Ptr { defaultVal = defaultVal.Elem() } if defaultVal.IsValid() && defaultVal.Type().AssignableTo(newValue.Type()) { newValue.Set(defaultVal) } if node.Type() != ast.NullType { if err := d.decodeValue(ctx, newValue, node); err != nil { return reflect.Value{}, err } } return d.castToAssignableValue(newValue, typ, node) } func (d *Decoder) keyToNodeMap(ctx context.Context, node ast.Node, ignoreMergeKey bool, getKeyOrValueNode func(*ast.MapNodeIter) ast.Node) (map[string]ast.Node, error) { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return nil, ErrExceededMaxDepth } mapNode, err := d.getMapNode(node, false) if err != nil { return nil, err } keyMap := map[string]struct{}{} keyToNodeMap := map[string]ast.Node{} mapIter := mapNode.MapRange() for mapIter.Next() { keyNode := mapIter.Key() if keyNode.IsMergeKey() { if ignoreMergeKey { continue } mergeMap, err := d.keyToNodeMap(ctx, mapIter.Value(), ignoreMergeKey, getKeyOrValueNode) if err != nil { return nil, err } for k, v := range mergeMap { if err := d.validateDuplicateKey(keyMap, k, v); err != nil { return nil, err } keyToNodeMap[k] = v } } else { keyVal, err := d.nodeToValue(ctx, keyNode) if err != nil { return nil, err } key, ok := keyVal.(string) if !ok { return nil, err } if err := d.validateDuplicateKey(keyMap, key, keyNode); err != nil { return nil, err } keyToNodeMap[key] = getKeyOrValueNode(mapIter) } } return keyToNodeMap, nil } func (d *Decoder) keyToKeyNodeMap(ctx context.Context, node ast.Node, ignoreMergeKey bool) (map[string]ast.Node, error) { m, err := d.keyToNodeMap(ctx, node, ignoreMergeKey, func(nodeMap *ast.MapNodeIter) ast.Node { return nodeMap.Key() }) if err != nil { return nil, err } return m, nil } func (d *Decoder) keyToValueNodeMap(ctx context.Context, node ast.Node, ignoreMergeKey bool) (map[string]ast.Node, error) { m, err := d.keyToNodeMap(ctx, node, ignoreMergeKey, func(nodeMap *ast.MapNodeIter) ast.Node { return nodeMap.Value() }) if err != nil { return nil, err } return m, nil } func (d *Decoder) setDefaultValueIfConflicted(v reflect.Value, fieldMap StructFieldMap) error { for v.Type().Kind() == reflect.Ptr { v = v.Elem() } typ := v.Type() if typ.Kind() != reflect.Struct { return nil } embeddedStructFieldMap, err := structFieldMap(typ) if err != nil { return err } for i := 0; i < typ.NumField(); i++ { field := typ.Field(i) if isIgnoredStructField(field) { continue } structField := embeddedStructFieldMap[field.Name] if !fieldMap.isIncludedRenderName(structField.RenderName) { continue } // if declared same key name, set default value fieldValue := v.Field(i) if fieldValue.CanSet() { fieldValue.Set(reflect.Zero(fieldValue.Type())) } } return nil } // This is a subset of the formats allowed by the regular expression // defined at http://yaml.org/type/timestamp.html. var allowedTimestampFormats = []string{ "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields. "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t". "2006-1-2 15:4:5.999999999", // space separated with no time zone "2006-1-2", // date only } func (d *Decoder) castToTime(ctx context.Context, src ast.Node) (time.Time, error) { if src == nil { return time.Time{}, nil } v, err := d.nodeToValue(ctx, src) if err != nil { return time.Time{}, err } if t, ok := v.(time.Time); ok { return t, nil } s, ok := v.(string) if !ok { return time.Time{}, errors.ErrTypeMismatch(reflect.TypeOf(time.Time{}), reflect.TypeOf(v), src.GetToken()) } for _, format := range allowedTimestampFormats { t, err := time.Parse(format, s) if err != nil { // invalid format continue } return t, nil } return time.Time{}, nil } func (d *Decoder) decodeTime(ctx context.Context, dst reflect.Value, src ast.Node) error { t, err := d.castToTime(ctx, src) if err != nil { return err } dst.Set(reflect.ValueOf(t)) return nil } func (d *Decoder) castToDuration(ctx context.Context, src ast.Node) (time.Duration, error) { if src == nil { return 0, nil } v, err := d.nodeToValue(ctx, src) if err != nil { return 0, err } if t, ok := v.(time.Duration); ok { return t, nil } s, ok := v.(string) if !ok { return 0, errors.ErrTypeMismatch(reflect.TypeOf(time.Duration(0)), reflect.TypeOf(v), src.GetToken()) } t, err := time.ParseDuration(s) if err != nil { return 0, err } return t, nil } func (d *Decoder) decodeDuration(ctx context.Context, dst reflect.Value, src ast.Node) error { t, err := d.castToDuration(ctx, src) if err != nil { return err } dst.Set(reflect.ValueOf(t)) return nil } // getMergeAliasName support single alias only func (d *Decoder) getMergeAliasName(src ast.Node) string { mapNode, err := d.getMapNode(src, true) if err != nil { return "" } mapIter := mapNode.MapRange() for mapIter.Next() { key := mapIter.Key() value := mapIter.Value() if key.IsMergeKey() && value.Type() == ast.AliasType { return value.(*ast.AliasNode).Value.GetToken().Value } } return "" } func (d *Decoder) decodeStruct(ctx context.Context, dst reflect.Value, src ast.Node) error { if src == nil { return nil } d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return ErrExceededMaxDepth } structType := dst.Type() srcValue := reflect.ValueOf(src) srcType := srcValue.Type() if srcType.Kind() == reflect.Ptr { srcType = srcType.Elem() srcValue = srcValue.Elem() } if structType == srcType { // dst value implements ast.Node dst.Set(srcValue) return nil } structFieldMap, err := structFieldMap(structType) if err != nil { return err } ignoreMergeKey := structFieldMap.hasMergeProperty() keyToNodeMap, err := d.keyToValueNodeMap(ctx, src, ignoreMergeKey) if err != nil { return err } var unknownFields map[string]ast.Node if d.disallowUnknownField { unknownFields, err = d.keyToKeyNodeMap(ctx, src, ignoreMergeKey) if err != nil { return err } } aliasName := d.getMergeAliasName(src) var foundErr error for i := 0; i < structType.NumField(); i++ { field := structType.Field(i) if isIgnoredStructField(field) { continue } structField := structFieldMap[field.Name] if structField.IsInline { fieldValue := dst.FieldByName(field.Name) if structField.IsAutoAlias { if aliasName != "" { newFieldValue := d.anchorValueMap[aliasName] if newFieldValue.IsValid() { value, err := d.castToAssignableValue(newFieldValue, fieldValue.Type(), d.anchorNodeMap[aliasName]) if err != nil { return err } fieldValue.Set(value) } } continue } if !fieldValue.CanSet() { return fmt.Errorf("cannot set embedded type as unexported field %s.%s", field.PkgPath, field.Name) } if fieldValue.Type().Kind() == reflect.Ptr && src.Type() == ast.NullType { // set nil value to pointer fieldValue.Set(reflect.Zero(fieldValue.Type())) continue } mapNode := ast.Mapping(nil, false) for k, v := range keyToNodeMap { key := &ast.StringNode{BaseNode: &ast.BaseNode{}, Value: k} mapNode.Values = append(mapNode.Values, ast.MappingValue(nil, key, v)) } newFieldValue, err := d.createDecodedNewValue(ctx, fieldValue.Type(), fieldValue, mapNode) if d.disallowUnknownField { if err := d.deleteStructKeys(fieldValue.Type(), unknownFields); err != nil { return err } } if err != nil { if foundErr != nil { continue } var te *errors.TypeError if errors.As(err, &te) { if te.StructFieldName != nil { fieldName := fmt.Sprintf("%s.%s", structType.Name(), *te.StructFieldName) te.StructFieldName = &fieldName } else { fieldName := fmt.Sprintf("%s.%s", structType.Name(), field.Name) te.StructFieldName = &fieldName } foundErr = te continue } else { foundErr = err } continue } _ = d.setDefaultValueIfConflicted(newFieldValue, structFieldMap) fieldValue.Set(newFieldValue) continue } v, exists := keyToNodeMap[structField.RenderName] if !exists { continue } delete(unknownFields, structField.RenderName) fieldValue := dst.FieldByName(field.Name) if fieldValue.Type().Kind() == reflect.Ptr && src.Type() == ast.NullType { // set nil value to pointer fieldValue.Set(reflect.Zero(fieldValue.Type())) continue } newFieldValue, err := d.createDecodedNewValue(ctx, fieldValue.Type(), fieldValue, v) if err != nil { if foundErr != nil { continue } var te *errors.TypeError if errors.As(err, &te) { fieldName := fmt.Sprintf("%s.%s", structType.Name(), field.Name) te.StructFieldName = &fieldName foundErr = te } else { foundErr = err } continue } fieldValue.Set(newFieldValue) } if foundErr != nil { return foundErr } // Ignore unknown fields when parsing an inline struct (recognized by a nil token). // Unknown fields are expected (they could be fields from the parent struct). if len(unknownFields) != 0 && d.disallowUnknownField && src.GetToken() != nil { for key, node := range unknownFields { return errors.ErrUnknownField(fmt.Sprintf(`unknown field "%s"`, key), node.GetToken()) } } if d.validator != nil { if err := d.validator.Struct(dst.Addr().Interface()); err != nil { ev := reflect.ValueOf(err) if ev.Type().Kind() == reflect.Slice { for i := 0; i < ev.Len(); i++ { fieldErr, ok := ev.Index(i).Interface().(FieldError) if !ok { continue } fieldName := fieldErr.StructField() structField, exists := structFieldMap[fieldName] if !exists { continue } node, exists := keyToNodeMap[structField.RenderName] if exists { // TODO: to make FieldError message cutomizable return errors.ErrSyntax( fmt.Sprintf("%s", err), d.getParentMapTokenIfExistsForValidationError(node.Type(), node.GetToken()), ) } else if t := src.GetToken(); t != nil && t.Prev != nil && t.Prev.Prev != nil { // A missing required field will not be in the keyToNodeMap // the error needs to be associated with the parent of the source node return errors.ErrSyntax(fmt.Sprintf("%s", err), t.Prev.Prev) } } } return err } } return nil } // getParentMapTokenIfExists if the NodeType is a container type such as MappingType or SequenceType, // it is necessary to return the parent MapNode's colon token to represent the entire container. func (d *Decoder) getParentMapTokenIfExistsForValidationError(typ ast.NodeType, tk *token.Token) *token.Token { if tk == nil { return nil } if typ == ast.MappingType { // map: // key: value // ^ current token ( colon ) if tk.Prev == nil { return tk } key := tk.Prev if key.Prev == nil { return tk } return key.Prev } if typ == ast.SequenceType { // map: // - value // ^ current token ( sequence entry ) if tk.Prev == nil { return tk } return tk.Prev } return tk } func (d *Decoder) decodeArray(ctx context.Context, dst reflect.Value, src ast.Node) error { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return ErrExceededMaxDepth } arrayNode, err := d.getArrayNode(src) if err != nil { return err } if arrayNode == nil { return nil } iter := arrayNode.ArrayRange() arrayValue := reflect.New(dst.Type()).Elem() arrayType := dst.Type() elemType := arrayType.Elem() idx := 0 var foundErr error for iter.Next() { v := iter.Value() if elemType.Kind() == reflect.Ptr && v.Type() == ast.NullType { // set nil value to pointer arrayValue.Index(idx).Set(reflect.Zero(elemType)) } else { dstValue, err := d.createDecodedNewValue(ctx, elemType, reflect.Value{}, v) if err != nil { if foundErr == nil { foundErr = err } continue } arrayValue.Index(idx).Set(dstValue) } idx++ } dst.Set(arrayValue) if foundErr != nil { return foundErr } return nil } func (d *Decoder) decodeSlice(ctx context.Context, dst reflect.Value, src ast.Node) error { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return ErrExceededMaxDepth } arrayNode, err := d.getArrayNode(src) if err != nil { return err } if arrayNode == nil { return nil } iter := arrayNode.ArrayRange() sliceType := dst.Type() sliceValue := reflect.MakeSlice(sliceType, 0, iter.Len()) elemType := sliceType.Elem() var foundErr error for iter.Next() { v := iter.Value() if elemType.Kind() == reflect.Ptr && v.Type() == ast.NullType { // set nil value to pointer sliceValue = reflect.Append(sliceValue, reflect.Zero(elemType)) continue } dstValue, err := d.createDecodedNewValue(ctx, elemType, reflect.Value{}, v) if err != nil { if foundErr == nil { foundErr = err } continue } sliceValue = reflect.Append(sliceValue, dstValue) } dst.Set(sliceValue) if foundErr != nil { return foundErr } return nil } func (d *Decoder) decodeMapItem(ctx context.Context, dst *MapItem, src ast.Node) error { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return ErrExceededMaxDepth } mapNode, err := d.getMapNode(src, isMerge(ctx)) if err != nil { return err } mapIter := mapNode.MapRange() if !mapIter.Next() { return nil } key := mapIter.Key() value := mapIter.Value() if key.IsMergeKey() { if err := d.decodeMapItem(withMerge(ctx), dst, value); err != nil { return err } return nil } k, err := d.nodeToValue(ctx, key) if err != nil { return err } v, err := d.nodeToValue(ctx, value) if err != nil { return err } *dst = MapItem{Key: k, Value: v} return nil } func (d *Decoder) validateDuplicateKey(keyMap map[string]struct{}, key interface{}, keyNode ast.Node) error { k, ok := key.(string) if !ok { return nil } if !d.allowDuplicateMapKey { if _, exists := keyMap[k]; exists { return errors.ErrDuplicateKey(fmt.Sprintf(`duplicate key "%s"`, k), keyNode.GetToken()) } } keyMap[k] = struct{}{} return nil } func (d *Decoder) decodeMapSlice(ctx context.Context, dst *MapSlice, src ast.Node) error { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return ErrExceededMaxDepth } mapNode, err := d.getMapNode(src, isMerge(ctx)) if err != nil { return err } mapSlice := MapSlice{} mapIter := mapNode.MapRange() keyMap := map[string]struct{}{} for mapIter.Next() { key := mapIter.Key() value := mapIter.Value() if key.IsMergeKey() { var m MapSlice if err := d.decodeMapSlice(withMerge(ctx), &m, value); err != nil { return err } for _, v := range m { if err := d.validateDuplicateKey(keyMap, v.Key, value); err != nil { return err } mapSlice = append(mapSlice, v) } continue } k, err := d.nodeToValue(ctx, key) if err != nil { return err } if err := d.validateDuplicateKey(keyMap, k, key); err != nil { return err } v, err := d.nodeToValue(ctx, value) if err != nil { return err } mapSlice = append(mapSlice, MapItem{Key: k, Value: v}) } *dst = mapSlice return nil } func (d *Decoder) decodeMap(ctx context.Context, dst reflect.Value, src ast.Node) error { d.stepIn() defer d.stepOut() if d.isExceededMaxDepth() { return ErrExceededMaxDepth } mapNode, err := d.getMapNode(src, isMerge(ctx)) if err != nil { return err } mapType := dst.Type() mapValue := reflect.MakeMap(mapType) keyType := mapValue.Type().Key() valueType := mapValue.Type().Elem() mapIter := mapNode.MapRange() keyMap := map[string]struct{}{} var foundErr error for mapIter.Next() { key := mapIter.Key() value := mapIter.Value() if key.IsMergeKey() { if err := d.decodeMap(withMerge(ctx), dst, value); err != nil { return err } iter := dst.MapRange() for iter.Next() { if err := d.validateDuplicateKey(keyMap, iter.Key(), value); err != nil { return err } mapValue.SetMapIndex(iter.Key(), iter.Value()) } continue } k := d.createDecodableValue(keyType) if d.canDecodeByUnmarshaler(k) { if err := d.decodeByUnmarshaler(ctx, k, key); err != nil { return err } } else { keyVal, err := d.nodeToValue(ctx, key) if err != nil { return err } k = reflect.ValueOf(keyVal) if k.IsValid() && k.Type().ConvertibleTo(keyType) { k = k.Convert(keyType) } } if k.IsValid() { if err := d.validateDuplicateKey(keyMap, k.Interface(), key); err != nil { return err } } if valueType.Kind() == reflect.Ptr && value.Type() == ast.NullType { // set nil value to pointer mapValue.SetMapIndex(k, reflect.Zero(valueType)) continue } dstValue, err := d.createDecodedNewValue(ctx, valueType, reflect.Value{}, value) if err != nil { if foundErr == nil { foundErr = err } } if !k.IsValid() { // expect nil key mapValue.SetMapIndex(d.createDecodableValue(keyType), dstValue) continue } if keyType.Kind() != k.Kind() { return errors.ErrSyntax( fmt.Sprintf("cannot convert %q type to %q type", k.Kind(), keyType.Kind()), key.GetToken(), ) } mapValue.SetMapIndex(k, dstValue) } dst.Set(mapValue) if foundErr != nil { return foundErr } return nil } func (d *Decoder) fileToReader(file string) (io.Reader, error) { reader, err := os.Open(file) if err != nil { return nil, err } return reader, nil } func (d *Decoder) isYAMLFile(file string) bool { ext := filepath.Ext(file) if ext == ".yml" { return true } if ext == ".yaml" { return true } return false } func (d *Decoder) readersUnderDir(dir string) ([]io.Reader, error) { pattern := fmt.Sprintf("%s/*", dir) matches, err := filepath.Glob(pattern) if err != nil { return nil, err } readers := []io.Reader{} for _, match := range matches { if !d.isYAMLFile(match) { continue } reader, err := d.fileToReader(match) if err != nil { return nil, err } readers = append(readers, reader) } return readers, nil } func (d *Decoder) readersUnderDirRecursive(dir string) ([]io.Reader, error) { readers := []io.Reader{} if err := filepath.Walk(dir, func(path string, info os.FileInfo, _ error) error { if !d.isYAMLFile(path) { return nil } reader, readerErr := d.fileToReader(path) if readerErr != nil { return readerErr } readers = append(readers, reader) return nil }); err != nil { return nil, err } return readers, nil } func (d *Decoder) resolveReference(ctx context.Context) error { for _, opt := range d.opts { if err := opt(d); err != nil { return err } } for _, file := range d.referenceFiles { reader, err := d.fileToReader(file) if err != nil { return err } d.referenceReaders = append(d.referenceReaders, reader) } for _, dir := range d.referenceDirs { if !d.isRecursiveDir { readers, err := d.readersUnderDir(dir) if err != nil { return err } d.referenceReaders = append(d.referenceReaders, readers...) } else { readers, err := d.readersUnderDirRecursive(dir) if err != nil { return err } d.referenceReaders = append(d.referenceReaders, readers...) } } for _, reader := range d.referenceReaders { bytes, err := io.ReadAll(reader) if err != nil { return err } // assign new anchor definition to anchorMap if _, err := d.parse(ctx, bytes); err != nil { return err } } d.isResolvedReference = true return nil } func (d *Decoder) parse(ctx context.Context, bytes []byte) (*ast.File, error) { var parseMode parser.Mode if d.toCommentMap != nil { parseMode = parser.ParseComments } var opts []parser.Option if d.allowDuplicateMapKey { opts = append(opts, parser.AllowDuplicateMapKey()) } f, err := parser.ParseBytes(bytes, parseMode, opts...) if err != nil { return nil, err } normalizedFile := &ast.File{} for _, doc := range f.Docs { // try to decode ast.Node to value and map anchor value to anchorMap v, err := d.nodeToValue(ctx, doc.Body) if err != nil { return nil, err } if v != nil || (doc.Body != nil && doc.Body.Type() == ast.NullType) { normalizedFile.Docs = append(normalizedFile.Docs, doc) cm := CommentMap{} maps.Copy(cm, d.toCommentMap) d.commentMaps = append(d.commentMaps, cm) } for k := range d.toCommentMap { delete(d.toCommentMap, k) } } return normalizedFile, nil } func (d *Decoder) isInitialized() bool { return d.parsedFile != nil } func (d *Decoder) decodeInit(ctx context.Context) error { if !d.isResolvedReference { if err := d.resolveReference(ctx); err != nil { return err } } var buf bytes.Buffer if _, err := io.Copy(&buf, d.reader); err != nil { return err } file, err := d.parse(ctx, buf.Bytes()) if err != nil { return err } d.parsedFile = file return nil } func (d *Decoder) decode(ctx context.Context, v reflect.Value) error { d.decodeDepth = 0 d.anchorValueMap = make(map[string]reflect.Value) if len(d.parsedFile.Docs) == 0 { // empty document. dst := v.Elem() if dst.IsValid() { dst.Set(reflect.Zero(dst.Type())) } } if len(d.parsedFile.Docs) <= d.streamIndex { return io.EOF } body := d.parsedFile.Docs[d.streamIndex].Body if body == nil { return nil } if len(d.commentMaps) > d.streamIndex { maps.Copy(d.toCommentMap, d.commentMaps[d.streamIndex]) } if err := d.decodeValue(ctx, v.Elem(), body); err != nil { return err } d.streamIndex++ return nil } // Decode reads the next YAML-encoded value from its input // and stores it in the value pointed to by v. // // See the documentation for Unmarshal for details about the // conversion of YAML into a Go value. func (d *Decoder) Decode(v interface{}) error { return d.DecodeContext(context.Background(), v) } // DecodeContext reads the next YAML-encoded value from its input // and stores it in the value pointed to by v with context.Context. func (d *Decoder) DecodeContext(ctx context.Context, v interface{}) error { rv := reflect.ValueOf(v) if !rv.IsValid() || rv.Type().Kind() != reflect.Ptr { return ErrDecodeRequiredPointerType } if d.isInitialized() { if err := d.decode(ctx, rv); err != nil { return err } return nil } if err := d.decodeInit(ctx); err != nil { return err } if err := d.decode(ctx, rv); err != nil { return err } return nil } // DecodeFromNode decodes node into the value pointed to by v. func (d *Decoder) DecodeFromNode(node ast.Node, v interface{}) error { return d.DecodeFromNodeContext(context.Background(), node, v) } // DecodeFromNodeContext decodes node into the value pointed to by v with context.Context. func (d *Decoder) DecodeFromNodeContext(ctx context.Context, node ast.Node, v interface{}) error { rv := reflect.ValueOf(v) if rv.Type().Kind() != reflect.Ptr { return ErrDecodeRequiredPointerType } if !d.isInitialized() { if err := d.decodeInit(ctx); err != nil { return err } } // resolve references to the anchor on the same file if _, err := d.nodeToValue(ctx, node); err != nil { return err } if err := d.decodeValue(ctx, rv.Elem(), node); err != nil { return err } return nil } goccy-go-yaml-52dacb8/decode_test.go000066400000000000000000002320101501576637100174750ustar00rootroot00000000000000package yaml_test import ( "bytes" "context" "fmt" "io" "log" "math" "net" "reflect" "strconv" "strings" "testing" "time" "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" "github.com/goccy/go-yaml/parser" ) type Child struct { B int C int `yaml:"-"` } type TestString string func TestDecoder(t *testing.T) { tests := []struct { source string value interface{} eof bool }{ { source: "v: hi\n", value: map[string]string{"v": "hi"}, }, { source: "v: hi\n", value: map[string]TestString{"v": "hi"}, }, { source: "v: \"true\"\n", value: map[string]string{"v": "true"}, }, { source: "v: \"false\"\n", value: map[string]string{"v": "false"}, }, { source: "v: true\n", value: map[string]interface{}{"v": true}, }, { source: "v: true\n", value: map[string]string{"v": "true"}, }, { source: "v: 10\n", value: map[string]string{"v": "10"}, }, { source: "v: 10\n", value: map[string]TestString{"v": "10"}, }, { source: "v: -10\n", value: map[string]string{"v": "-10"}, }, { source: "v: 1.234\n", value: map[string]string{"v": "1.234"}, }, { source: "v: \" foo\"\n", value: map[string]string{"v": " foo"}, }, { source: "v: \"foo \"\n", value: map[string]string{"v": "foo "}, }, { source: "v: \" foo \"\n", value: map[string]string{"v": " foo "}, }, { source: "v: false\n", value: map[string]bool{"v": false}, }, { source: "v: 10\n", value: map[string]int{"v": 10}, }, { source: "v: 10", value: map[string]interface{}{"v": 10}, }, { source: "v: 0b10", value: map[string]interface{}{"v": 2}, }, { source: "v: -0b101010", value: map[string]interface{}{"v": -42}, }, { source: "v: -0b1000000000000000000000000000000000000000000000000000000000000000", value: map[string]interface{}{"v": int64(-9223372036854775808)}, }, { source: "v: 0xA", value: map[string]interface{}{"v": 10}, }, { source: "v: .1", value: map[string]interface{}{"v": 0.1}, }, { source: "v: -.1", value: map[string]interface{}{"v": -0.1}, }, { source: "v: -10\n", value: map[string]int{"v": -10}, }, { source: "v: 4294967296\n", value: map[string]int64{"v": int64(4294967296)}, }, { source: "v: 0.1\n", value: map[string]interface{}{"v": 0.1}, }, { source: "v: 0.99\n", value: map[string]float32{"v": 0.99}, }, { source: "v: -0.1\n", value: map[string]float64{"v": -0.1}, }, { source: "v: 6.8523e+5", value: map[string]interface{}{"v": 6.8523e+5}, }, { source: "v: 685.230_15e+03", value: map[string]interface{}{"v": 685.23015e+03}, }, { source: "v: 685_230.15", value: map[string]interface{}{"v": 685230.15}, }, { source: "v: 685_230.15", value: map[string]float64{"v": 685230.15}, }, { source: "v: 685230", value: map[string]interface{}{"v": 685230}, }, { source: "v: +685_230", value: map[string]interface{}{"v": 685230}, }, { source: "v: 02472256", value: map[string]interface{}{"v": 685230}, }, { source: "v: 0x_0A_74_AE", value: map[string]interface{}{"v": 685230}, }, { source: "v: 0b1010_0111_0100_1010_1110", value: map[string]interface{}{"v": 685230}, }, { source: "v: +685_230", value: map[string]int{"v": 685230}, }, // Bools from spec { source: "v: True", value: map[string]interface{}{"v": true}, }, { source: "v: TRUE", value: map[string]interface{}{"v": true}, }, { source: "v: False", value: map[string]interface{}{"v": false}, }, { source: "v: FALSE", value: map[string]interface{}{"v": false}, }, { source: "v: y", value: map[string]interface{}{"v": "y"}, // y or yes or Yes is string }, { source: "v: NO", value: map[string]interface{}{"v": "NO"}, // no or No or NO is string }, { source: "v: on", value: map[string]interface{}{"v": "on"}, // on is string }, // Some cross type conversions { source: "v: 42", value: map[string]uint{"v": 42}, }, { source: "v: 4294967296", value: map[string]uint64{"v": uint64(4294967296)}, }, // int { source: "v: 2147483647", value: map[string]int{"v": math.MaxInt32}, }, { source: "v: -2147483648", value: map[string]int{"v": math.MinInt32}, }, // int64 { source: "v: 9223372036854775807", value: map[string]int64{"v": math.MaxInt64}, }, { source: "v: 0b111111111111111111111111111111111111111111111111111111111111111", value: map[string]int64{"v": math.MaxInt64}, }, { source: "v: -9223372036854775808", value: map[string]int64{"v": math.MinInt64}, }, { source: "v: -0b111111111111111111111111111111111111111111111111111111111111111", value: map[string]int64{"v": -math.MaxInt64}, }, // uint { source: "v: 0", value: map[string]uint{"v": 0}, }, { source: "v: 4294967295", value: map[string]uint{"v": math.MaxUint32}, }, { source: "v: 1e3", value: map[string]uint{"v": 1000}, }, // uint64 { source: "v: 0", value: map[string]uint{"v": 0}, }, { source: "v: 18446744073709551615", value: map[string]uint64{"v": math.MaxUint64}, }, { source: "v: 0b1111111111111111111111111111111111111111111111111111111111111111", value: map[string]uint64{"v": math.MaxUint64}, }, { source: "v: 9223372036854775807", value: map[string]uint64{"v": math.MaxInt64}, }, { source: "v: 1e3", value: map[string]uint64{"v": 1000}, }, // float32 { source: "v: 3.40282346638528859811704183484516925440e+38", value: map[string]float32{"v": math.MaxFloat32}, }, { source: "v: 1.401298464324817070923729583289916131280e-45", value: map[string]float32{"v": math.SmallestNonzeroFloat32}, }, { source: "v: 18446744073709551615", value: map[string]float32{"v": float32(math.MaxUint64)}, }, { source: "v: 18446744073709551616", value: map[string]float32{"v": float32(math.MaxUint64 + 1)}, }, { source: "v: 1e-06", value: map[string]float32{"v": 1e-6}, }, // float64 { source: "v: 1.797693134862315708145274237317043567981e+308", value: map[string]float64{"v": math.MaxFloat64}, }, { source: "v: 4.940656458412465441765687928682213723651e-324", value: map[string]float64{"v": math.SmallestNonzeroFloat64}, }, { source: "v: 18446744073709551615", value: map[string]float64{"v": float64(math.MaxUint64)}, }, { source: "v: 18446744073709551616", value: map[string]float64{"v": float64(math.MaxUint64 + 1)}, }, { source: "v: 1e-06", value: map[string]float64{"v": 1e-06}, }, // Timestamps { // Date only. source: "v: 2015-01-01\n", value: map[string]time.Time{"v": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, }, { // RFC3339 source: "v: 2015-02-24T18:19:39.12Z\n", value: map[string]time.Time{"v": time.Date(2015, 2, 24, 18, 19, 39, .12e9, time.UTC)}, }, { // RFC3339 with short dates. source: "v: 2015-2-3T3:4:5Z", value: map[string]time.Time{"v": time.Date(2015, 2, 3, 3, 4, 5, 0, time.UTC)}, }, { // ISO8601 lower case t source: "v: 2015-02-24t18:19:39Z\n", value: map[string]time.Time{"v": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)}, }, { // space separate, no time zone source: "v: 2015-02-24 18:19:39\n", value: map[string]time.Time{"v": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)}, }, { source: "v: 60s\n", value: map[string]time.Duration{"v": time.Minute}, }, { source: "v: -0.5h\n", value: map[string]time.Duration{"v": -30 * time.Minute}, }, // Single Quoted values. { source: `'1': '2'`, value: map[interface{}]interface{}{"1": `2`}, }, { source: `'1': '"2"'`, value: map[interface{}]interface{}{"1": `"2"`}, }, { source: `'1': ''''`, value: map[interface{}]interface{}{"1": `'`}, }, { source: `'1': '''2'''`, value: map[interface{}]interface{}{"1": `'2'`}, }, { source: `'1': 'B''z'`, value: map[interface{}]interface{}{"1": `B'z`}, }, { source: `'1': '\'`, value: map[interface{}]interface{}{"1": `\`}, }, { source: `'1': '\\'`, value: map[interface{}]interface{}{"1": `\\`}, }, { source: `'1': '\"2\"'`, value: map[interface{}]interface{}{"1": `\"2\"`}, }, { source: `'1': '\\"2\\"'`, value: map[interface{}]interface{}{"1": `\\"2\\"`}, }, { source: "'1': ' 1\n 2\n 3'", value: map[interface{}]interface{}{"1": " 1 2 3"}, }, { source: "'1': '\n 2\n 3'", value: map[interface{}]interface{}{"1": " 2 3"}, }, // Double Quoted values. { source: `"1": "2"`, value: map[interface{}]interface{}{"1": `2`}, }, { source: `"1": "\"2\""`, value: map[interface{}]interface{}{"1": `"2"`}, }, { source: `"1": "\""`, value: map[interface{}]interface{}{"1": `"`}, }, { source: `"1": "X\"z"`, value: map[interface{}]interface{}{"1": `X"z`}, }, { source: `"1": "\\"`, value: map[interface{}]interface{}{"1": `\`}, }, { source: `"1": "\\\\"`, value: map[interface{}]interface{}{"1": `\\`}, }, { source: `"1": "\\\"2\\\""`, value: map[interface{}]interface{}{"1": `\"2\"`}, }, { source: "'1': \" 1\n 2\n 3\"", value: map[interface{}]interface{}{"1": " 1 2 3"}, }, { source: "'1': \"\n 2\n 3\"", value: map[interface{}]interface{}{"1": " 2 3"}, }, { source: `"1": "a\x2Fb"`, value: map[interface{}]interface{}{"1": `a/b`}, }, { source: `"1": "a\u002Fb"`, value: map[interface{}]interface{}{"1": `a/b`}, }, { source: `"1": "a\x2Fb\u002Fc\U0000002Fd"`, value: map[interface{}]interface{}{"1": `a/b/c/d`}, }, { source: "'1': \"2\\n3\"", value: map[interface{}]interface{}{"1": "2\n3"}, }, { source: "'1': \"2\\r\\n3\"", value: map[interface{}]interface{}{"1": "2\r\n3"}, }, { source: "'1': \"a\\\nb\\\nc\"", value: map[interface{}]interface{}{"1": "abc"}, }, { source: "'1': \"a\\\r\nb\\\r\nc\"", value: map[interface{}]interface{}{"1": "abc"}, }, { source: "'1': \"a\\\rb\\\rc\"", value: map[interface{}]interface{}{"1": "abc"}, }, { source: "a: -b_c", value: map[string]interface{}{"a": "-b_c"}, }, { source: "a: +b_c", value: map[string]interface{}{"a": "+b_c"}, }, { source: "a: 50cent_of_dollar", value: map[string]interface{}{"a": "50cent_of_dollar"}, }, // Nulls { source: "null", value: (*struct{})(nil), }, { source: "~", value: (*struct{})(nil), }, { source: "v:", value: map[string]interface{}{"v": nil}, }, { source: "v: ~", value: map[string]interface{}{"v": nil}, }, { source: "~: null key", value: map[interface{}]string{nil: "null key"}, }, { source: "v:", value: map[string]*bool{"v": nil}, }, { source: "v: null", value: map[string]*string{"v": nil}, }, { source: "v: null", value: map[string]string{"v": ""}, }, { source: "v: null", value: map[string]interface{}{"v": nil}, }, { source: "v: Null", value: map[string]interface{}{"v": nil}, }, { source: "v: NULL", value: map[string]interface{}{"v": nil}, }, { source: "v: ~", value: map[string]*string{"v": nil}, }, { source: "v: ~", value: map[string]string{"v": ""}, }, { source: "v: .inf\n", value: map[string]interface{}{"v": math.Inf(0)}, }, { source: "v: .Inf\n", value: map[string]interface{}{"v": math.Inf(0)}, }, { source: "v: .INF\n", value: map[string]interface{}{"v": math.Inf(0)}, }, { source: "v: -.inf\n", value: map[string]interface{}{"v": math.Inf(-1)}, }, { source: "v: -.Inf\n", value: map[string]interface{}{"v": math.Inf(-1)}, }, { source: "v: -.INF\n", value: map[string]interface{}{"v": math.Inf(-1)}, }, { source: "v: .nan\n", value: map[string]interface{}{"v": math.NaN()}, }, { source: "v: .NaN\n", value: map[string]interface{}{"v": math.NaN()}, }, { source: "v: .NAN\n", value: map[string]interface{}{"v": math.NaN()}, }, // Explicit tags. { source: "v: !!float '1.1'", value: map[string]interface{}{"v": 1.1}, }, { source: "v: !!float 0", value: map[string]interface{}{"v": float64(0)}, }, { source: "v: !!float -1", value: map[string]interface{}{"v": float64(-1)}, }, { source: "v: !!null ''", value: map[string]interface{}{"v": nil}, }, { source: "v: !!timestamp \"2015-01-01\"", value: map[string]time.Time{"v": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, }, { source: "v: !!timestamp 2015-01-01", value: map[string]time.Time{"v": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)}, }, { source: "v: !!bool yes", value: map[string]bool{"v": true}, }, { source: "v: !!bool False", value: map[string]bool{"v": false}, }, { source: ` !!merge <<: { a: 1, b: 2 } c: 3 `, value: map[string]any{"a": 1, "b": 2, "c": 3}, }, // merge { source: ` a: &a foo: 1 b: &b bar: 2 merge: <<: [*a, *b] `, value: map[string]map[string]any{ "a": {"foo": 1}, "b": {"bar": 2}, "merge": {"foo": 1, "bar": 2}, }, }, { source: ` a: &a foo: 1 b: &b bar: 2 merge: <<: [*a, *b] `, value: map[string]yaml.MapSlice{ "a": {{Key: "foo", Value: 1}}, "b": {{Key: "bar", Value: 2}}, "merge": {{Key: "foo", Value: 1}, {Key: "bar", Value: 2}}, }, }, // Flow sequence { source: "v: [A,B]", value: map[string]interface{}{"v": []interface{}{"A", "B"}}, }, { source: "v: [A,B,C,]", value: map[string][]string{"v": {"A", "B", "C"}}, }, { source: "v: [A,1,C]", value: map[string][]string{"v": {"A", "1", "C"}}, }, { source: "v: [A,1,C]", value: map[string]interface{}{"v": []interface{}{"A", 1, "C"}}, }, { source: "v: [a: b, c: d]", value: map[string]any{"v": []any{ map[string]any{"a": "b"}, map[string]any{"c": "d"}, }}, }, { source: "v: [{a: b}, {c: d, e: f}]", value: map[string]any{"v": []any{ map[string]any{"a": "b"}, map[string]any{ "c": "d", "e": "f", }, }}, }, // Block sequence { source: "v:\n - A\n - B", value: map[string]interface{}{"v": []interface{}{"A", "B"}}, }, { source: "v:\n - A\n - B\n - C", value: map[string][]string{"v": {"A", "B", "C"}}, }, { source: "v:\n - A\n - 1\n - C", value: map[string][]string{"v": {"A", "1", "C"}}, }, { source: "v:\n - A\n - 1\n - C", value: map[string]interface{}{"v": []interface{}{"A", 1, "C"}}, }, // Map inside interface with no type hints. { source: "a: {b: c}", value: map[interface{}]interface{}{"a": map[interface{}]interface{}{"b": "c"}}, }, { source: "v: \"\"\n", value: map[string]string{"v": ""}, }, { source: "v:\n- A\n- B\n", value: map[string][]string{"v": {"A", "B"}}, }, { source: "a: '-'\n", value: map[string]string{"a": "-"}, }, { source: "123\n", value: 123, }, { source: "hello: world\n", value: map[string]string{"hello": "world"}, }, { source: "hello: world\r\n", value: map[string]string{"hello": "world"}, }, { source: "hello: world\rGo: Gopher", value: map[string]string{"hello": "world", "Go": "Gopher"}, }, // Structs and type conversions. { source: "hello: world", value: struct{ Hello string }{"world"}, }, { source: "a: {b: c}", value: struct{ A struct{ B string } }{struct{ B string }{"c"}}, }, { source: "a: {b: c}", value: struct{ A map[string]string }{map[string]string{"b": "c"}}, }, { source: "a:", value: struct{ A map[string]string }{}, }, { source: "a: 1", value: struct{ A int }{1}, }, { source: "a: 1", value: struct{ A float64 }{1}, }, { source: "a: 1.0", value: struct{ A int }{1}, }, { source: "a: 1.0", value: struct{ A uint }{1}, }, { source: "a: [1, 2]", value: struct{ A []int }{[]int{1, 2}}, }, { source: "a: [1, 2]", value: struct{ A [2]int }{[2]int{1, 2}}, }, { source: "a: 1", value: struct{ B int }{0}, }, { source: "a: 1", value: struct { B int `yaml:"a"` }{1}, }, { source: "a: 1\n", value: yaml.MapItem{Key: "a", Value: 1}, }, { source: "a: 1\nb: 2\nc: 3\n", value: yaml.MapSlice{ {Key: "a", Value: 1}, {Key: "b", Value: 2}, {Key: "c", Value: 3}, }, }, { source: "v:\n- A\n- 1\n- B:\n - 2\n - 3\n", value: map[string]interface{}{ "v": []interface{}{ "A", 1, map[string][]int{ "B": {2, 3}, }, }, }, }, { source: "a:\n b: c\n", value: map[string]interface{}{ "a": map[string]string{ "b": "c", }, }, }, { source: "a: {x: 1}\n", value: map[string]map[string]int{ "a": { "x": 1, }, }, }, { source: "t2: 2018-01-09T10:40:47Z\nt4: 2098-01-09T10:40:47Z\n", value: map[string]string{ "t2": "2018-01-09T10:40:47Z", "t4": "2098-01-09T10:40:47Z", }, }, { source: "a: [1, 2]\n", value: map[string][]int{ "a": {1, 2}, }, }, { source: "a: {b: c, d: e}\n", value: map[string]interface{}{ "a": map[string]string{ "b": "c", "d": "e", }, }, }, { source: "a: 3s\n", value: map[string]string{ "a": "3s", }, }, { source: "a: \n", value: map[string]string{"a": ""}, }, { source: "a: \"1:1\"\n", value: map[string]string{"a": "1:1"}, }, { source: "a: 1.2.3.4\n", value: map[string]string{"a": "1.2.3.4"}, }, { source: "a: 'b: c'\n", value: map[string]string{"a": "b: c"}, }, { source: "a: 'Hello #comment'\n", value: map[string]string{"a": "Hello #comment"}, }, { source: "a: 100.5\n", value: map[string]interface{}{ "a": 100.5, }, }, { source: "a: \"\\0\"\n", value: map[string]string{"a": "\x00"}, }, { source: "b: 2\na: 1\nd: 4\nc: 3\nsub:\n e: 5\n", value: map[string]interface{}{ "b": 2, "a": 1, "d": 4, "c": 3, "sub": map[string]int{ "e": 5, }, }, }, { source: " a : b \n", value: map[string]string{"a": "b"}, }, { source: "a: b # comment\nb: c\n", value: map[string]string{ "a": "b", "b": "c", }, }, { source: "---\na: b\n", value: map[string]string{"a": "b"}, }, { source: "a: b\n...\n", value: map[string]string{"a": "b"}, }, { source: "%YAML 1.2\n---\n", value: (*struct{})(nil), eof: true, }, { source: "---\n", value: (*struct{})(nil), eof: true, }, { source: "...", value: (*struct{})(nil), eof: true, }, { source: "v: go test ./...", value: map[string]string{"v": "go test ./..."}, }, { source: "v: echo ---", value: map[string]string{"v": "echo ---"}, }, { source: "v: |\n hello\n ...\n world\n", value: map[string]string{"v": "hello\n...\nworld\n"}, }, { source: "a: !!binary gIGC\n", value: map[string]string{"a": "\x80\x81\x82"}, }, { source: "a: !!binary |\n " + strings.Repeat("kJCQ", 17) + "kJ\n CQ\n", value: map[string]string{"a": strings.Repeat("\x90", 54)}, }, { source: "v:\n- A\n- |-\n B\n C\n", value: map[string][]string{ "v": { "A", "B\nC", }, }, }, { source: "v:\n- A\n- |-\n B\n C\n\n\n", value: map[string][]string{ "v": { "A", "B\nC", }, }, }, { source: "v:\n- A\n- >-\n B\n C\n", value: map[string][]string{ "v": { "A", "B C", }, }, }, { source: "v:\n- A\n- >-\n B\n C\n\n\n", value: map[string][]string{ "v": { "A", "B C", }, }, }, { source: "a: b\nc: d\n", value: struct { A string C string `yaml:"c"` }{ "b", "d", }, }, { source: "a: 1\nb: 2\n", value: struct { A int B int `yaml:"-"` }{ 1, 0, }, }, { source: "a: 1\nb: 2\n", value: struct { A int Child `yaml:",inline"` }{ 1, Child{ B: 2, C: 0, }, }, }, // Anchors and aliases. { source: "a: &x 1\nb: &y 2\nc: *x\nd: *y\n", value: struct{ A, B, C, D int }{1, 2, 1, 2}, }, { source: "a: &a {c: 1}\nb: *a\n", value: struct { A, B struct { C int } }{struct{ C int }{1}, struct{ C int }{1}}, }, { source: "a: &a [1, 2]\nb: *a\n", value: struct{ B []int }{[]int{1, 2}}, }, { source: "key1: &anchor\n subkey: *anchor\nkey2: *anchor\n", value: map[string]any{ "key1": map[string]any{ "subkey": nil, }, "key2": map[string]any{ "subkey": nil, }, }, }, { source: `{a: &a c, *a : b}`, value: map[string]string{"a": "c", "c": "b"}, }, { source: "tags:\n- hello-world\na: foo", value: struct { Tags []string A string }{Tags: []string{"hello-world"}, A: "foo"}, }, { source: "", value: (*struct{})(nil), eof: true, }, { source: "{}", value: struct{}{}, }, { source: "{a: , b: c}", value: map[string]any{"a": nil, "b": "c"}, }, { source: "v: /a/{b}", value: map[string]string{"v": "/a/{b}"}, }, { source: "v: 1[]{},!%?&*", value: map[string]string{"v": "1[]{},!%?&*"}, }, { source: "v: user's item", value: map[string]string{"v": "user's item"}, }, { source: "v: [1,[2,[3,[4,5],6],7],8]", value: map[string]interface{}{ "v": []interface{}{ 1, []interface{}{ 2, []interface{}{ 3, []int{4, 5}, 6, }, 7, }, 8, }, }, }, { source: "v: {a: {b: {c: {d: e},f: g},h: i},j: k}", value: map[string]interface{}{ "v": map[string]interface{}{ "a": map[string]interface{}{ "b": map[string]interface{}{ "c": map[string]string{ "d": "e", }, "f": "g", }, "h": "i", }, "j": "k", }, }, }, { source: `--- - a: b: - c: d `, value: []map[string]interface{}{ { "a": map[string]interface{}{ "b": nil, }, }, { "c": "d", }, }, }, { source: `--- a: b: c: d `, value: map[string]interface{}{ "a": map[string]interface{}{ "b": nil, }, "c": "d", }, }, { source: `--- a: b: c: `, value: map[string]interface{}{ "a": nil, "b": nil, "c": nil, }, }, { source: `--- a: go test ./... b: c: `, value: map[string]interface{}{ "a": "go test ./...", "b": nil, "c": nil, }, }, { source: `--- a: | hello ... world b: c: `, value: map[string]interface{}{ "a": "hello\n...\nworld\n", "b": nil, "c": nil, }, }, // Multi bytes { source: "v: あいうえお\nv2: かきくけこ", value: map[string]string{"v": "あいうえお", "v2": "かきくけこ"}, }, { source: ` - "Fun with \\" - "\" \a \b \e \f" - "\n \r \t \v \0" - "\ \_ \N \L \P \ \x41 \u0041 \U00000041" `, value: []string{"Fun with \\", "\" \u0007 \b \u001b \f", "\n \r \t \u000b \u0000", "\u0020 \u00a0 \u0085 \u2028 \u2029 A A A"}, }, { source: `"\ud83e\udd23"`, value: "🤣", }, { source: `"\uD83D\uDE00\uD83D\uDE01"`, value: "😀😁", }, { source: `"\uD83D\uDE00a\uD83D\uDE01"`, value: "😀a😁", }, } for _, test := range tests { t.Run(test.source, func(t *testing.T) { buf := bytes.NewBufferString(test.source) dec := yaml.NewDecoder(buf) typ := reflect.ValueOf(test.value).Type() value := reflect.New(typ) if err := dec.Decode(value.Interface()); err != nil { if test.eof && err == io.EOF { return } t.Fatalf("%s: %+v", test.source, err) } if test.eof { t.Fatal("expected EOF but got no error") } actual := fmt.Sprintf("%+v", value.Elem().Interface()) expect := fmt.Sprintf("%+v", test.value) if actual != expect { t.Fatalf("failed to test [%s], actual=[%s], expect=[%s]", test.source, actual, expect) } }) } } func TestDecoder_Invalid(t *testing.T) { tests := []struct { src string expect string }{ { "*-0", ` [1:2] could not find alias "-0" > 1 | *-0 ^ `, }, } for _, test := range tests { t.Run(test.src, func(t *testing.T) { var v any err := yaml.Unmarshal([]byte(test.src), &v) if err == nil { t.Fatal("cannot catch decode error") } actual := "\n" + err.Error() if test.expect != actual { t.Fatalf("expected: [%s] but got [%s]", test.expect, actual) } }) } } func TestDecoder_ScientificNotation(t *testing.T) { tests := []struct { source string value interface{} }{ { "v: 1e3", map[string]uint{"v": 1000}, }, { "v: 1e-3", map[string]uint{"v": 0}, }, { "v: 1e3", map[string]int{"v": 1000}, }, { "v: 1e-3", map[string]int{"v": 0}, }, { "v: 1e3", map[string]float32{"v": 1000}, }, { "v: 1.0e3", map[string]float64{"v": 1000}, }, { "v: 1e-3", map[string]float64{"v": 0.001}, }, { "v: 1.0e-3", map[string]float64{"v": 0.001}, }, { "v: 1.0e+3", map[string]float64{"v": 1000}, }, { "v: 1.0e+3", map[string]float64{"v": 1000}, }, } for _, test := range tests { t.Run(test.source, func(t *testing.T) { buf := bytes.NewBufferString(test.source) dec := yaml.NewDecoder(buf) typ := reflect.ValueOf(test.value).Type() value := reflect.New(typ) if err := dec.Decode(value.Interface()); err != nil { if err == io.EOF { return } t.Fatalf("%s: %+v", test.source, err) } actual := fmt.Sprintf("%+v", value.Elem().Interface()) expect := fmt.Sprintf("%+v", test.value) if actual != expect { t.Fatalf("failed to test [%s], actual=[%s], expect=[%s]", test.source, actual, expect) } }) } } func TestDecoder_TypeConversionError(t *testing.T) { t.Run("type conversion for struct", func(t *testing.T) { type T struct { A int B uint C float32 D bool } type U struct { *T `yaml:",inline"` } t.Run("string to int", func(t *testing.T) { var v T err := yaml.Unmarshal([]byte(`a: str`), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal string into Go struct field T.A of type int" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } }) t.Run("string to uint", func(t *testing.T) { var v T err := yaml.Unmarshal([]byte(`b: str`), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal string into Go struct field T.B of type uint" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } }) t.Run("string to bool", func(t *testing.T) { var v T err := yaml.Unmarshal([]byte(`d: str`), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal string into Go struct field T.D of type bool" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } }) t.Run("string to int at inline", func(t *testing.T) { var v U err := yaml.Unmarshal([]byte(`a: str`), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal string into Go struct field U.T.A of type int" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } }) }) t.Run("type conversion for array", func(t *testing.T) { t.Run("string to int", func(t *testing.T) { var v map[string][]int err := yaml.Unmarshal([]byte(`v: [A,1,C]`), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal string into Go value of type int" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } }) t.Run("string to int", func(t *testing.T) { var v map[string][]int err := yaml.Unmarshal([]byte("v:\n - A\n - 1\n - C"), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal string into Go value of type int" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } }) }) t.Run("overflow error", func(t *testing.T) { t.Run("negative number to uint", func(t *testing.T) { var v map[string]uint err := yaml.Unmarshal([]byte("v: -42"), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal -42 into Go value of type uint ( overflow )" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } if v["v"] != 0 { t.Fatal("failed to decode value") } }) t.Run("negative number to uint64", func(t *testing.T) { var v map[string]uint64 err := yaml.Unmarshal([]byte("v: -4294967296"), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal -4294967296 into Go value of type uint64 ( overflow )" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } if v["v"] != 0 { t.Fatal("failed to decode value") } }) t.Run("larger number for int32", func(t *testing.T) { var v map[string]int32 err := yaml.Unmarshal([]byte("v: 4294967297"), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal 4294967297 into Go value of type int32 ( overflow )" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } if v["v"] != 0 { t.Fatal("failed to decode value") } }) t.Run("larger number for int8", func(t *testing.T) { var v map[string]int8 err := yaml.Unmarshal([]byte("v: 128"), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal 128 into Go value of type int8 ( overflow )" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } if v["v"] != 0 { t.Fatal("failed to decode value") } }) }) t.Run("type conversion for time", func(t *testing.T) { type T struct { A time.Time B time.Duration } t.Run("int to time", func(t *testing.T) { var v T err := yaml.Unmarshal([]byte(`a: 123`), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal uint64 into Go struct field T.A of type time.Time" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } }) t.Run("string to duration", func(t *testing.T) { var v T err := yaml.Unmarshal([]byte(`b: str`), &v) if err == nil { t.Fatal("expected to error") } msg := `time: invalid duration "str"` if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } }) t.Run("int to duration", func(t *testing.T) { var v T err := yaml.Unmarshal([]byte(`b: 10`), &v) if err == nil { t.Fatal("expected to error") } msg := "cannot unmarshal uint64 into Go struct field T.B of type time.Duration" if !strings.Contains(err.Error(), msg) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), msg) } }) }) } func TestDecoder_AnchorReferenceDirs(t *testing.T) { buf := bytes.NewBufferString("a: *a\n") dec := yaml.NewDecoder(buf, yaml.ReferenceDirs("testdata")) var v struct { A struct { B int C string } } if err := dec.Decode(&v); err != nil { t.Fatalf("%+v", err) } if v.A.B != 1 { t.Fatal("failed to decode by reference dirs") } if v.A.C != "hello" { t.Fatal("failed to decode by reference dirs") } } func TestDecoder_AnchorReferenceDirsRecursive(t *testing.T) { buf := bytes.NewBufferString("a: *a\n") dec := yaml.NewDecoder( buf, yaml.ReferenceDirs("testdata"), ) var v struct { A struct { B int C string } } if err := dec.Decode(&v); err != nil { t.Fatalf("%+v", err) } if v.A.B != 1 { t.Fatal("failed to decode by reference dirs") } if v.A.C != "hello" { t.Fatal("failed to decode by reference dirs") } } func TestDecoder_AnchorFiles(t *testing.T) { buf := bytes.NewBufferString("a: *a\n") dec := yaml.NewDecoder(buf, yaml.ReferenceFiles("testdata/anchor.yml")) var v struct { A struct { B int C string } } if err := dec.Decode(&v); err != nil { t.Fatalf("%+v", err) } if v.A.B != 1 { t.Fatal("failed to decode by reference dirs") } if v.A.C != "hello" { t.Fatal("failed to decode by reference dirs") } } func TestDecodeWithMergeKey(t *testing.T) { yml := ` a: &a b: 1 c: hello items: - <<: *a - <<: *a c: world ` type Item struct { B int C string } type T struct { Items []*Item } buf := bytes.NewBufferString(yml) dec := yaml.NewDecoder(buf, yaml.AllowDuplicateMapKey()) var v T if err := dec.Decode(&v); err != nil { t.Fatalf("%+v", err) } if len(v.Items) != 2 { t.Fatal("failed to decode with merge key") } if v.Items[0].B != 1 || v.Items[0].C != "hello" { t.Fatal("failed to decode with merge key") } if v.Items[1].B != 1 || v.Items[1].C != "world" { t.Fatal("failed to decode with merge key") } t.Run("decode with interface{}", func(t *testing.T) { buf := bytes.NewBufferString(yml) dec := yaml.NewDecoder(buf) var v interface{} if err := dec.Decode(&v); err != nil { t.Fatalf("%+v", err) } items, _ := v.(map[string]interface{})["items"].([]interface{}) if len(items) != 2 { t.Fatal("failed to decode with merge key") } b0 := items[0].(map[string]interface{})["b"] if _, ok := b0.(uint64); !ok { t.Fatal("failed to decode with merge key") } if b0.(uint64) != 1 { t.Fatal("failed to decode with merge key") } c0 := items[0].(map[string]interface{})["c"] if _, ok := c0.(string); !ok { t.Fatal("failed to decode with merge key") } if c0.(string) != "hello" { t.Fatal("failed to decode with merge key") } b1 := items[1].(map[string]interface{})["b"] if _, ok := b1.(uint64); !ok { t.Fatal("failed to decode with merge key") } if b1.(uint64) != 1 { t.Fatal("failed to decode with merge key") } c1 := items[1].(map[string]interface{})["c"] if _, ok := c1.(string); !ok { t.Fatal("failed to decode with merge key") } if c1.(string) != "world" { t.Fatal("failed to decode with merge key") } }) t.Run("decode with map", func(t *testing.T) { var v struct { Items []map[string]interface{} } buf := bytes.NewBufferString(yml) dec := yaml.NewDecoder(buf) if err := dec.Decode(&v); err != nil { t.Fatalf("%+v", err) } if len(v.Items) != 2 { t.Fatal("failed to decode with merge key") } b0 := v.Items[0]["b"] if _, ok := b0.(uint64); !ok { t.Fatal("failed to decode with merge key") } if b0.(uint64) != 1 { t.Fatal("failed to decode with merge key") } c0 := v.Items[0]["c"] if _, ok := c0.(string); !ok { t.Fatal("failed to decode with merge key") } if c0.(string) != "hello" { t.Fatal("failed to decode with merge key") } b1 := v.Items[1]["b"] if _, ok := b1.(uint64); !ok { t.Fatal("failed to decode with merge key") } if b1.(uint64) != 1 { t.Fatal("failed to decode with merge key") } c1 := v.Items[1]["c"] if _, ok := c1.(string); !ok { t.Fatal("failed to decode with merge key") } if c1.(string) != "world" { t.Fatal("failed to decode with merge key") } }) } func TestDecoder_Inline(t *testing.T) { type Base struct { A int B string } yml := `--- a: 1 b: hello c: true ` var v struct { *Base `yaml:",inline"` C bool } if err := yaml.NewDecoder(strings.NewReader(yml)).Decode(&v); err != nil { t.Fatalf("%+v", err) } if v.A != 1 { t.Fatal("failed to decode with inline key") } if v.B != "hello" { t.Fatal("failed to decode with inline key") } if !v.C { t.Fatal("failed to decode with inline key") } t.Run("multiple inline with strict", func(t *testing.T) { type Base struct { A int B string } type Base2 struct { Base *Base `yaml:",inline"` } yml := `--- a: 1 b: hello ` var v struct { Base2 *Base2 `yaml:",inline"` } if err := yaml.NewDecoder(strings.NewReader(yml), yaml.Strict()).Decode(&v); err != nil { t.Fatalf("%+v", err) } if v.Base2.Base.A != 1 { t.Fatal("failed to decode with inline key") } if v.Base2.Base.B != "hello" { t.Fatal("failed to decode with inline key") } }) } func TestDecoder_InlineAndConflictKey(t *testing.T) { type Base struct { A int B string } yml := `--- a: 1 b: hello c: true ` var v struct { *Base `yaml:",inline"` A int C bool } if err := yaml.NewDecoder(strings.NewReader(yml)).Decode(&v); err != nil { t.Fatalf("%+v", err) } if v.A != 1 { t.Fatal("failed to decode with inline key") } if v.B != "hello" { t.Fatal("failed to decode with inline key") } if !v.C { t.Fatal("failed to decode with inline key") } if v.Base.A != 0 { t.Fatal("failed to decode with inline key") } } func TestDecoder_InlineAndWrongTypeStrict(t *testing.T) { type Base struct { A int B string } yml := `--- a: notanint b: hello c: true ` var v struct { *Base `yaml:",inline"` C bool } err := yaml.NewDecoder(strings.NewReader(yml), yaml.Strict()).Decode(&v) if err == nil { t.Fatalf("expected error") } // TODO: properly check if errors are colored/have source t.Logf("%s", err) t.Logf("%s", yaml.FormatError(err, true, false)) t.Logf("%s", yaml.FormatError(err, false, true)) t.Logf("%s", yaml.FormatError(err, true, true)) } func TestDecoder_InvalidCases(t *testing.T) { const src = `--- a: - b c: d ` var v struct { A []string } err := yaml.NewDecoder(strings.NewReader(src)).Decode(&v) if err == nil { t.Fatalf("expected error") } if err.Error() != yaml.FormatError(err, false, true) { t.Logf("err.Error() = %s", err.Error()) t.Logf("yaml.FormatError(err, false, true) = %s", yaml.FormatError(err, false, true)) t.Fatal(`err.Error() should match yaml.FormatError(err, false, true)`) } // TODO: properly check if errors are colored/have source t.Logf("%s", err) t.Logf("%s", yaml.FormatError(err, true, false)) t.Logf("%s", yaml.FormatError(err, false, true)) t.Logf("%s", yaml.FormatError(err, true, true)) } func TestDecoder_JSONTags(t *testing.T) { var v struct { A string `json:"a_json"` // no YAML tag B string `json:"b_json" yaml:"b_yaml"` // both tags } const src = `--- a_json: a_json_value b_json: b_json_value b_yaml: b_yaml_value ` if err := yaml.NewDecoder(strings.NewReader(src)).Decode(&v); err != nil { t.Fatalf(`parsing should succeed: %s`, err) } if v.A != "a_json_value" { t.Fatalf("v.A should be `a_json_value`, got `%s`", v.A) } if v.B != "b_yaml_value" { t.Fatalf("v.B should be `b_yaml_value`, got `%s`", v.B) } } func TestDecoder_DisallowUnknownField(t *testing.T) { t.Run("different level keys with same name", func(t *testing.T) { var v struct { C Child `yaml:"c"` } yml := `--- b: 1 c: b: 1 ` err := yaml.NewDecoder(strings.NewReader(yml), yaml.DisallowUnknownField()).Decode(&v) if err == nil { t.Fatalf("error expected") } }) t.Run("inline", func(t *testing.T) { var v struct { *Child `yaml:",inline"` A string `yaml:"a"` } yml := `--- a: a b: 1 ` if err := yaml.NewDecoder(strings.NewReader(yml), yaml.DisallowUnknownField()).Decode(&v); err != nil { t.Fatalf(`parsing should succeed: %s`, err) } if v.A != "a" { t.Fatalf("v.A should be `a`, got `%s`", v.A) } if v.B != 1 { t.Fatalf("v.B should be 1, got %d", v.B) } if v.C != 0 { t.Fatalf("v.C should be 0, got %d", v.C) } }) t.Run("list", func(t *testing.T) { type C struct { Child `yaml:",inline"` } var v struct { Children []C `yaml:"children"` } yml := `--- children: - b: 1 - b: 2 ` if err := yaml.NewDecoder(strings.NewReader(yml), yaml.DisallowUnknownField()).Decode(&v); err != nil { t.Fatalf(`parsing should succeed: %s`, err) } if len(v.Children) != 2 { t.Fatalf(`len(v.Children) should be 2, got %d`, len(v.Children)) } if v.Children[0].B != 1 { t.Fatalf(`v.Children[0].B should be 1, got %d`, v.Children[0].B) } if v.Children[1].B != 2 { t.Fatalf(`v.Children[1].B should be 2, got %d`, v.Children[1].B) } }) } func TestDecoder_AllowDuplicateMapKey(t *testing.T) { yml := ` a: b a: c ` t.Run("map", func(t *testing.T) { var v map[string]string if err := yaml.NewDecoder(strings.NewReader(yml), yaml.AllowDuplicateMapKey()).Decode(&v); err != nil { t.Fatal(err) } }) t.Run("struct", func(t *testing.T) { var v struct { A string } if err := yaml.NewDecoder(strings.NewReader(yml), yaml.AllowDuplicateMapKey()).Decode(&v); err != nil { t.Fatal(err) } }) } func TestDecoder_DefaultValues(t *testing.T) { v := struct { A string `yaml:"a"` B string `yaml:"b"` c string // private D struct { E string `yaml:"e"` F struct { G string `yaml:"g"` } `yaml:"f"` H struct { I string `yaml:"i"` } `yaml:",inline"` } `yaml:"d"` J struct { K string `yaml:"k"` L struct { M string `yaml:"m"` } `yaml:"l"` N struct { O string `yaml:"o"` } `yaml:",inline"` } `yaml:",inline"` P struct { Q string `yaml:"q"` R struct { S string `yaml:"s"` } `yaml:"r"` T struct { U string `yaml:"u"` } `yaml:",inline"` } `yaml:"p"` V struct { W string `yaml:"w"` X struct { Y string `yaml:"y"` } `yaml:"x"` Z struct { Ä string `yaml:"ä"` } `yaml:",inline"` } `yaml:",inline"` }{ B: "defaultBValue", c: "defaultCValue", } v.D.E = "defaultEValue" v.D.F.G = "defaultGValue" v.D.H.I = "defaultIValue" v.J.K = "defaultKValue" v.J.L.M = "defaultMValue" v.J.N.O = "defaultOValue" v.P.R.S = "defaultSValue" v.P.T.U = "defaultUValue" v.V.X.Y = "defaultYValue" v.V.Z.Ä = "defaultÄValue" const src = `--- a: a_value p: q: q_value w: w_value ` if err := yaml.NewDecoder(strings.NewReader(src)).Decode(&v); err != nil { t.Fatalf(`parsing should succeed: %s`, err) } if v.A != "a_value" { t.Fatalf("v.A should be `a_value`, got `%s`", v.A) } if v.B != "defaultBValue" { t.Fatalf("v.B should be `defaultValue`, got `%s`", v.B) } if v.c != "defaultCValue" { t.Fatalf("v.c should be `defaultCValue`, got `%s`", v.c) } if v.D.E != "defaultEValue" { t.Fatalf("v.D.E should be `defaultEValue`, got `%s`", v.D.E) } if v.D.F.G != "defaultGValue" { t.Fatalf("v.D.F.G should be `defaultGValue`, got `%s`", v.D.F.G) } if v.D.H.I != "defaultIValue" { t.Fatalf("v.D.H.I should be `defaultIValue`, got `%s`", v.D.H.I) } if v.J.K != "defaultKValue" { t.Fatalf("v.J.K should be `defaultKValue`, got `%s`", v.J.K) } if v.J.L.M != "defaultMValue" { t.Fatalf("v.J.L.M should be `defaultMValue`, got `%s`", v.J.L.M) } if v.J.N.O != "defaultOValue" { t.Fatalf("v.J.N.O should be `defaultOValue`, got `%s`", v.J.N.O) } if v.P.Q != "q_value" { t.Fatalf("v.P.Q should be `q_value`, got `%s`", v.P.Q) } if v.P.R.S != "defaultSValue" { t.Fatalf("v.P.R.S should be `defaultSValue`, got `%s`", v.P.R.S) } if v.P.T.U != "defaultUValue" { t.Fatalf("v.P.T.U should be `defaultUValue`, got `%s`", v.P.T.U) } if v.V.W != "w_value" { t.Fatalf("v.V.W should be `w_value`, got `%s`", v.V.W) } if v.V.X.Y != "defaultYValue" { t.Fatalf("v.V.X.Y should be `defaultYValue`, got `%s`", v.V.X.Y) } if v.V.Z.Ä != "defaultÄValue" { t.Fatalf("v.V.Z.Ä should be `defaultÄValue`, got `%s`", v.V.Z.Ä) } } func ExampleUnmarshal_yAMLTags() { yml := `--- foo: 1 bar: c A: 2 B: d ` var v struct { A int `yaml:"foo" json:"A"` B string `yaml:"bar" json:"B"` } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { log.Fatal(err) } fmt.Println(v.A) fmt.Println(v.B) // OUTPUT: // 1 // c } type useJSONUnmarshalerTest struct { s string } func (t *useJSONUnmarshalerTest) UnmarshalJSON(b []byte) error { s, err := strconv.Unquote(string(b)) if err != nil { return err } t.s = s return nil } func TestDecoder_UseJSONUnmarshaler(t *testing.T) { var v useJSONUnmarshalerTest if err := yaml.UnmarshalWithOptions([]byte(`"a"`), &v, yaml.UseJSONUnmarshaler()); err != nil { t.Fatal(err) } if v.s != "a" { t.Fatalf("unexpected decoded value: %s", v.s) } } func TestDecoder_CustomUnmarshaler(t *testing.T) { t.Run("override struct type", func(t *testing.T) { type T struct { Foo string `yaml:"foo"` } src := []byte(`foo: "bar"`) var v T if err := yaml.UnmarshalWithOptions(src, &v, yaml.CustomUnmarshaler[T](func(dst *T, b []byte) error { if !bytes.Equal(src, b) { t.Fatalf("failed to get decode target buffer. expected %q but got %q", src, b) } var v T if err := yaml.Unmarshal(b, &v); err != nil { return err } if v.Foo != "bar" { t.Fatal("failed to decode") } dst.Foo = "bazbaz" // assign another value to target return nil })); err != nil { t.Fatal(err) } if v.Foo != "bazbaz" { t.Fatalf("failed to switch to custom unmarshaler. got: %v", v.Foo) } }) t.Run("override bytes type", func(t *testing.T) { type T struct { Foo []byte `yaml:"foo"` } src := []byte(`foo: "bar"`) var v T if err := yaml.UnmarshalWithOptions(src, &v, yaml.CustomUnmarshaler[[]byte](func(dst *[]byte, b []byte) error { if !bytes.Equal(b, []byte(`"bar"`)) { t.Fatalf("failed to get target buffer: %q", b) } *dst = []byte("bazbaz") return nil })); err != nil { t.Fatal(err) } if !bytes.Equal(v.Foo, []byte("bazbaz")) { t.Fatalf("failed to switch to custom unmarshaler. got: %q", v.Foo) } }) t.Run("override bytes type with context", func(t *testing.T) { type T struct { Foo []byte `yaml:"foo"` } src := []byte(`foo: "bar"`) var v T ctx := context.WithValue(context.Background(), "plop", uint(42)) if err := yaml.UnmarshalContext(ctx, src, &v, yaml.CustomUnmarshalerContext[[]byte](func(ctx context.Context, dst *[]byte, b []byte) error { if !bytes.Equal(b, []byte(`"bar"`)) { t.Fatalf("failed to get target buffer: %q", b) } if ctx.Value("plop") != uint(42) { t.Fatalf("context value is not correct") } *dst = []byte("bazbaz") return nil })); err != nil { t.Fatal(err) } if !bytes.Equal(v.Foo, []byte("bazbaz")) { t.Fatalf("failed to switch to custom unmarshaler. got: %q", v.Foo) } }) } type unmarshalContext struct { v int } func (c *unmarshalContext) UnmarshalYAML(ctx context.Context, b []byte) error { v, ok := ctx.Value("k").(int) if !ok { return errors.New("cannot get valid context") } if v != 1 { return errors.New("cannot get valid context") } if string(b) != "1" { return errors.New("cannot get valid bytes") } c.v = v return nil } func Test_UnmarshalerContext(t *testing.T) { ctx := context.WithValue(context.Background(), "k", 1) var v unmarshalContext if err := yaml.UnmarshalContext(ctx, []byte(`1`), &v); err != nil { t.Fatalf("%+v", err) } if v.v != 1 { t.Fatal("cannot call UnmarshalYAML") } } func TestDecoder_DecodeFromNode(t *testing.T) { t.Run("has reference", func(t *testing.T) { str := ` anchor: &map text: hello map: *map` var buf bytes.Buffer dec := yaml.NewDecoder(&buf) f, err := parser.ParseBytes([]byte(str), 0) if err != nil { t.Fatalf("failed to parse: %s", err) } type T struct { Map map[string]string } var v T if err := dec.DecodeFromNode(f.Docs[0].Body, &v); err != nil { t.Fatalf("failed to decode: %s", err) } actual := fmt.Sprintf("%+v", v) expect := fmt.Sprintf("%+v", T{map[string]string{"text": "hello"}}) if actual != expect { t.Fatalf("actual=[%s], expect=[%s]", actual, expect) } }) t.Run("with reference option", func(t *testing.T) { anchor := strings.NewReader(` map: &map text: hello`) var buf bytes.Buffer dec := yaml.NewDecoder(&buf, yaml.ReferenceReaders(anchor)) f, err := parser.ParseBytes([]byte("map: *map"), 0) if err != nil { t.Fatalf("failed to parse: %s", err) } type T struct { Map map[string]string } var v T if err := dec.DecodeFromNode(f.Docs[0].Body, &v); err != nil { t.Fatalf("failed to decode: %s", err) } actual := fmt.Sprintf("%+v", v) expect := fmt.Sprintf("%+v", T{map[string]string{"text": "hello"}}) if actual != expect { t.Fatalf("actual=[%s], expect=[%s]", actual, expect) } }) t.Run("value is not pointer", func(t *testing.T) { var buf bytes.Buffer var v bool err := yaml.NewDecoder(&buf).DecodeFromNode(nil, v) if !errors.Is(err, yaml.ErrDecodeRequiredPointerType) { t.Fatalf("unexpected error: %s", err) } }) } func TestCommentWithCustomUnmarshaler(t *testing.T) { type T struct{} for idx, test := range []string{ ` foo: # comment - a: b `, ` foo: # comment bar: 1 baz: true `, } { t.Run(strconv.Itoa(idx), func(t *testing.T) { m := yaml.CommentMap{} var v T if err := yaml.UnmarshalWithOptions( []byte(test), &v, yaml.CommentToMap(m), yaml.CustomUnmarshaler[T](func(dst *T, b []byte) error { expected := bytes.Trim([]byte(test), "\n") if !bytes.Equal(b, expected) { return fmt.Errorf("failed to decode: got\n%s", string(test)) } return nil }), ); err != nil { t.Fatal(err) } }) } } func ExampleUnmarshal_jSONTags() { yml := `--- foo: 1 bar: c ` var v struct { A int `json:"foo"` B string `json:"bar"` } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { log.Fatal(err) } fmt.Println(v.A) fmt.Println(v.B) // OUTPUT: // 1 // c } func ExampleDecoder_Decode_disallowUnknownField() { var v struct { A string `yaml:"simple"` C string `yaml:"complicated"` } const src = `--- simple: string unknown: string ` err := yaml.NewDecoder(strings.NewReader(src), yaml.DisallowUnknownField()).Decode(&v) fmt.Printf("%v\n", err) // OUTPUT: // [3:1] unknown field "unknown" // 1 | --- // 2 | simple: string // > 3 | unknown: string // ^ } func ExampleNodeToValue() { f, err := parser.ParseBytes([]byte("text: node example"), 0) if err != nil { panic(err) } var v struct { Text string `yaml:"text"` } if err := yaml.NodeToValue(f.Docs[0].Body, &v); err != nil { panic(err) } fmt.Println(v.Text) // OUTPUT: // node example } type unmarshalableYAMLStringValue string func (v *unmarshalableYAMLStringValue) UnmarshalYAML(b []byte) error { var s string if err := yaml.Unmarshal(b, &s); err != nil { return err } *v = unmarshalableYAMLStringValue(s) return nil } type unmarshalableTextStringValue string func (v *unmarshalableTextStringValue) UnmarshalText(b []byte) error { *v = unmarshalableTextStringValue(string(b)) return nil } type unmarshalableStringContainer struct { A unmarshalableYAMLStringValue `yaml:"a"` B unmarshalableTextStringValue `yaml:"b"` } func TestUnmarshalableString(t *testing.T) { t.Run("empty string", func(t *testing.T) { t.Parallel() yml := ` a: "" b: "" ` var container unmarshalableStringContainer if err := yaml.Unmarshal([]byte(yml), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.A != "" { t.Fatalf("expected empty string, but %q is set", container.A) } if container.B != "" { t.Fatalf("expected empty string, but %q is set", container.B) } }) t.Run("filled string", func(t *testing.T) { t.Parallel() yml := ` a: "aaa" b: "bbb" ` var container unmarshalableStringContainer if err := yaml.Unmarshal([]byte(yml), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.A != "aaa" { t.Fatalf("expected \"aaa\", but %q is set", container.A) } if container.B != "bbb" { t.Fatalf("expected \"bbb\", but %q is set", container.B) } }) t.Run("single-quoted string", func(t *testing.T) { t.Parallel() yml := ` a: 'aaa' b: 'bbb' ` var container unmarshalableStringContainer if err := yaml.Unmarshal([]byte(yml), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.A != "aaa" { t.Fatalf("expected \"aaa\", but %q is set", container.A) } if container.B != "bbb" { t.Fatalf("expected \"aaa\", but %q is set", container.B) } }) t.Run("literal", func(t *testing.T) { t.Parallel() yml := ` a: | a b c b: | a b c ` var container unmarshalableStringContainer if err := yaml.Unmarshal([]byte(yml), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.A != "a\nb\nc\n" { t.Fatalf("expected \"a\nb\nc\n\", but %q is set", container.A) } if container.B != "a\nb\nc\n" { t.Fatalf("expected \"a\nb\nc\n\", but %q is set", container.B) } }) t.Run("anchor/alias", func(t *testing.T) { yml := ` a: &x 1 b: *x c: &y hello d: *y ` var v struct { A, B, C, D unmarshalableTextStringValue } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } if v.A != "1" { t.Fatal("failed to unmarshal") } if v.B != "1" { t.Fatal("failed to unmarshal") } if v.C != "hello" { t.Fatal("failed to unmarshal") } if v.D != "hello" { t.Fatal("failed to unmarshal") } }) t.Run("net.IP", func(t *testing.T) { yml := ` a: &a 127.0.0.1 b: *a ` var v struct { A, B net.IP } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } if v.A.String() != net.IPv4(127, 0, 0, 1).String() { t.Fatal("failed to unmarshal") } if v.B.String() != net.IPv4(127, 0, 0, 1).String() { t.Fatal("failed to unmarshal") } }) t.Run("quoted map keys", func(t *testing.T) { t.Parallel() yml := ` a: "b" : 2 'c': true ` var v struct { A struct { B int C bool } } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatalf("failed to unmarshal %v", err) } if v.A.B != 2 { t.Fatalf("expected a.b to equal 2 but was %d", v.A.B) } if !v.A.C { t.Fatal("expected a.c to be true but was false") } }) } type unmarshalablePtrStringContainer struct { V *string `yaml:"value"` } func TestUnmarshalablePtrString(t *testing.T) { t.Run("empty string", func(t *testing.T) { t.Parallel() var container unmarshalablePtrStringContainer if err := yaml.Unmarshal([]byte(`value: ""`), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.V == nil || *container.V != "" { t.Fatalf("expected empty string, but %q is set", *container.V) } }) t.Run("null", func(t *testing.T) { t.Parallel() var container unmarshalablePtrStringContainer if err := yaml.Unmarshal([]byte(`value: null`), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.V != (*string)(nil) { t.Fatalf("expected nil, but %q is set", *container.V) } }) } type unmarshalableIntValue int func (v *unmarshalableIntValue) UnmarshalYAML(raw []byte) error { i, err := strconv.Atoi(string(raw)) if err != nil { return err } *v = unmarshalableIntValue(i) return nil } type unmarshalableIntContainer struct { V unmarshalableIntValue `yaml:"value"` } func TestUnmarshalableInt(t *testing.T) { t.Run("empty int", func(t *testing.T) { t.Parallel() var container unmarshalableIntContainer if err := yaml.Unmarshal([]byte(``), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.V != 0 { t.Fatalf("expected empty int, but %d is set", container.V) } }) t.Run("filled int", func(t *testing.T) { t.Parallel() var container unmarshalableIntContainer if err := yaml.Unmarshal([]byte(`value: 9`), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.V != 9 { t.Fatalf("expected 9, but %d is set", container.V) } }) t.Run("filled number", func(t *testing.T) { t.Parallel() var container unmarshalableIntContainer if err := yaml.Unmarshal([]byte(`value: 9`), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.V != 9 { t.Fatalf("expected 9, but %d is set", container.V) } }) } type unmarshalablePtrIntContainer struct { V *int `yaml:"value"` } func TestUnmarshalablePtrInt(t *testing.T) { t.Run("empty int", func(t *testing.T) { t.Parallel() var container unmarshalablePtrIntContainer if err := yaml.Unmarshal([]byte(`value: 0`), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.V == nil || *container.V != 0 { t.Fatalf("expected 0, but %q is set", *container.V) } }) t.Run("null", func(t *testing.T) { t.Parallel() var container unmarshalablePtrIntContainer if err := yaml.Unmarshal([]byte(`value: null`), &container); err != nil { t.Fatalf("failed to unmarshal %v", err) } if container.V != (*int)(nil) { t.Fatalf("expected nil, but %q is set", *container.V) } }) } type literalContainer struct { v string } func (c *literalContainer) UnmarshalYAML(v []byte) error { var lit string if err := yaml.Unmarshal(v, &lit); err != nil { return err } c.v = lit return nil } func TestDecode_Literal(t *testing.T) { yml := `--- value: | { "key": "value" } ` var v map[string]*literalContainer if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatalf("failed to unmarshal %+v", err) } if v["value"] == nil { t.Fatal("failed to unmarshal literal with bytes unmarshaler") } if v["value"].v == "" { t.Fatal("failed to unmarshal literal with bytes unmarshaler") } } func TestDecoder_UseOrderedMap(t *testing.T) { yml := ` a: b c: d e: f: g h: i j: k ` var v interface{} if err := yaml.NewDecoder(strings.NewReader(yml), yaml.UseOrderedMap()).Decode(&v); err != nil { t.Fatalf("%+v", err) } if _, ok := v.(yaml.MapSlice); !ok { t.Fatalf("failed to convert to ordered map: %T", v) } bytes, err := yaml.Marshal(v) if err != nil { t.Fatalf("%+v", err) } if string(yml) != "\n"+string(bytes) { t.Fatalf("expected:[%s] actual:[%s]", string(yml), "\n"+string(bytes)) } } func TestDecoder_Stream(t *testing.T) { yml := ` --- a: b c: d --- e: f g: h --- i: j k: l ` dec := yaml.NewDecoder(strings.NewReader(yml)) values := []map[string]string{} for { var v map[string]string if err := dec.Decode(&v); err != nil { if err == io.EOF { break } t.Fatalf("%+v", err) } values = append(values, v) } if len(values) != 3 { t.Fatal("failed to stream decoding") } if values[0]["a"] != "b" { t.Fatal("failed to stream decoding") } if values[1]["e"] != "f" { t.Fatal("failed to stream decoding") } if values[2]["i"] != "j" { t.Fatal("failed to stream decoding") } } type unmarshalYAMLWithAliasString string func (v *unmarshalYAMLWithAliasString) UnmarshalYAML(b []byte) error { var s string if err := yaml.Unmarshal(b, &s); err != nil { return err } *v = unmarshalYAMLWithAliasString(s) return nil } type unmarshalYAMLWithAliasMap map[string]interface{} func (v *unmarshalYAMLWithAliasMap) UnmarshalYAML(b []byte) error { var m map[string]interface{} if err := yaml.Unmarshal(b, &m); err != nil { return err } *v = unmarshalYAMLWithAliasMap(m) return nil } func TestDecoder_UnmarshalYAMLWithAlias(t *testing.T) { type value struct { String unmarshalYAMLWithAliasString Map unmarshalYAMLWithAliasMap } tests := []struct { name string yaml string expectedValue value err string }{ { name: "ok", yaml: ` anchors: w: &w "\"hello\" \"world\"" map: &x a: b c: d d: *w string: *w map: <<: *x e: f `, expectedValue: value{ String: unmarshalYAMLWithAliasString(`"hello" "world"`), Map: unmarshalYAMLWithAliasMap(map[string]interface{}{ "a": "b", "c": "d", "d": `"hello" "world"`, "e": "f", }), }, }, { name: "unknown alias", yaml: ` anchors: w: &w "\"hello\" \"world\"" map: &x a: b c: d d: *w string: *y map: <<: *z e: f `, err: `could not find alias "y"`, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { var v value err := yaml.Unmarshal([]byte(test.yaml), &v) if test.err != "" { if err == nil { t.Fatal("expected to error") } if !strings.Contains(err.Error(), test.err) { t.Fatalf("expected error message: %s to contain: %s", err.Error(), test.err) } } else { if err != nil { t.Fatalf("%+v", err) } if !reflect.DeepEqual(test.expectedValue, v) { t.Fatalf("non matching values:\nexpected[%s]\ngot [%s]", test.expectedValue, v) } } }) } } type unmarshalString string func (u *unmarshalString) UnmarshalYAML(b []byte) error { *u = unmarshalString(string(b)) return nil } type unmarshalList struct { v []map[string]unmarshalString } func (u *unmarshalList) UnmarshalYAML(b []byte) error { expected := ` - b: c # comment # comment d: | # comment hello hello f: g - h: i` actual := "\n" + string(b) if expected != actual { return fmt.Errorf("unexpected bytes: expected [%q] but got [%q]", expected, actual) } var v []map[string]unmarshalString if err := yaml.Unmarshal(b, &v); err != nil { return err } u.v = v return nil } func TestDecoder_DecodeWithAnchorAnyValue(t *testing.T) { type Config struct { Env []string `json:"env"` } type Schema struct { Def map[string]any `json:"def"` Config Config `json:"config"` } data := ` def: myenv: &my_env - VAR1=1 - VAR2=2 config: env: *my_env ` var cfg Schema if err := yaml.NewDecoder(strings.NewReader(data)).Decode(&cfg); err != nil { t.Fatal(err) } if !reflect.DeepEqual(cfg.Config.Env, []string{"VAR1=1", "VAR2=2"}) { t.Fatalf("failed to decode value. actual = %+v", cfg) } } func TestDecoder_UnmarshalBytesWithSeparatedList(t *testing.T) { yml := ` a: - b: c # comment # comment d: | # comment hello hello f: g - h: i ` var v struct { A unmarshalList } cm := yaml.CommentMap{} if err := yaml.UnmarshalWithOptions([]byte(yml), &v, yaml.CommentToMap(cm)); err != nil { t.Fatal(err) } if len(v.A.v) != 2 { t.Fatalf("failed to unmarshal %+v", v) } if len(v.A.v[0]) != 3 { t.Fatalf("failed to unmarshal %+v", v.A.v[0]) } if len(v.A.v[1]) != 1 { t.Fatalf("failed to unmarshal %+v", v.A.v[1]) } } func TestDecoder_LiteralWithNewLine(t *testing.T) { type A struct { Node string `yaml:"b"` LastNode string `yaml:"last"` } tests := []A{ { Node: "hello\nworld", }, { Node: "hello\nworld\n", }, { LastNode: "hello\nworld", }, { LastNode: "hello\nworld\n", }, } // struct(want) -> Marshal -> Unmarchal -> struct(got) for _, want := range tests { bytes, _ := yaml.Marshal(want) got := A{} if err := yaml.Unmarshal(bytes, &got); err != nil { t.Fatal(err) } if want.Node != got.Node { t.Fatalf("expected:%q but got %q", want.Node, got.Node) } if want.LastNode != got.LastNode { t.Fatalf("expected:%q but got %q", want.LastNode, got.LastNode) } } } func TestDecoder_TabCharacterAtRight(t *testing.T) { yml := ` - a: [2 , 2] b: [2 , 2] c: [2 , 2]` var v []map[string][]int if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } if len(v) != 1 { t.Fatalf("failed to unmarshal %+v", v) } if len(v[0]) != 3 { t.Fatalf("failed to unmarshal %+v", v) } } func TestDecoder_Canonical(t *testing.T) { yml := ` !!map { ? !!str "explicit":!!str "entry", ? !!str "implicit" : !!str "entry", ? !!null "" : !!null "", } ` var v interface{} if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatalf("%+v", err) } m, ok := v.(map[string]interface{}) if !ok { t.Fatalf("failed to decode canonical yaml: %+v", v) } if m["explicit"] != "entry" { t.Fatalf("failed to decode canonical yaml: %+v", m) } if m["implicit"] != "entry" { t.Fatalf("failed to decode canonical yaml: %+v", m) } if m["null"] != nil { t.Fatalf("failed to decode canonical yaml: %+v", m) } } func TestDecoder_DecodeFromFile(t *testing.T) { yml := ` a: b c: d ` file, err := parser.ParseBytes([]byte(yml), 0) if err != nil { t.Fatal(err) } var v map[string]string if err := yaml.NewDecoder(file).Decode(&v); err != nil { t.Fatal(err) } if len(v) != 2 { t.Fatal("failed to decode from ast.File") } if v["a"] != "b" { t.Fatal("failed to decode from ast.File") } if v["c"] != "d" { t.Fatal("failed to decode from ast.File") } } func TestDecoder_DecodeWithNode(t *testing.T) { t.Run("abstract node", func(t *testing.T) { type T struct { Text ast.Node `yaml:"text"` } var v T if err := yaml.Unmarshal([]byte(`text: hello`), &v); err != nil { t.Fatalf("%+v", err) } expected := "hello" got := v.Text.String() if expected != got { t.Fatalf("failed to decode to ast.Node: expected %s but got %s", expected, got) } }) t.Run("concrete node", func(t *testing.T) { type T struct { Text *ast.StringNode `yaml:"text"` } var v T if err := yaml.Unmarshal([]byte(`text: hello`), &v); err != nil { t.Fatalf("%+v", err) } expected := "hello" got := v.Text.String() if expected != got { t.Fatalf("failed to decode to ast.Node: expected %s but got %s", expected, got) } }) } func TestRoundtripAnchorAlias(t *testing.T) { t.Run("irreversible", func(t *testing.T) { type foo struct { K1 string K2 string } type bar struct { K1 string K3 string } type doc struct { Foo foo Bar bar } yml := ` foo: <<: &test-anchor k1: "One" k2: "Two" bar: <<: *test-anchor k3: "Three" ` var v doc if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatalf("%+v", err) } bytes, err := yaml.Marshal(v) if err != nil { t.Fatalf("%+v", err) } expected := ` foo: k1: One k2: Two bar: k1: One k3: Three ` got := "\n" + string(bytes) if expected != got { t.Fatalf("expected:[%s] but got [%s]", expected, got) } }) t.Run("reversible", func(t *testing.T) { type TestAnchor struct { K1 string } type foo struct { *TestAnchor `yaml:",inline,alias"` K2 string } type bar struct { *TestAnchor `yaml:",inline,alias"` K3 string } type doc struct { TestAnchor *TestAnchor `yaml:"test-anchor,anchor"` Foo foo Bar bar } yml := ` test-anchor: &test-anchor k1: One foo: <<: *test-anchor k2: Two bar: <<: *test-anchor k3: Three ` var v doc if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatalf("%+v", err) } bytes, err := yaml.Marshal(v) if err != nil { t.Fatalf("%+v", err) } got := "\n" + string(bytes) if yml != got { t.Fatalf("expected:[%s] but got [%s]", yml, got) } }) } func TestDecodeWithSameAnchor(t *testing.T) { yml := ` a: &a 1 b: &a 2 c: &a 3 d: *a ` type T struct { A int B int C int D int } var v T if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } if !reflect.DeepEqual(v, T{A: 1, B: 2, C: 3, D: 3}) { t.Fatalf("failed to decode same anchor: %+v", v) } } func TestUnmarshalMapSliceParallel(t *testing.T) { content := ` steps: req0: desc: Get /users/1 req: /users/1: get: nil test: | current.res.status == 200 req1: desc: Get /private req: /private: get: nil test: | current.res.status == 403 req2: desc: Get /users req: /users: get: nil test: | current.res.status == 200 ` type mappedSteps struct { Steps yaml.MapSlice `yaml:"steps,omitempty"` } for i := 0; i < 100; i++ { t.Run(fmt.Sprintf("i=%d", i), func(t *testing.T) { t.Parallel() for i := 0; i < 10; i++ { m := mappedSteps{ Steps: yaml.MapSlice{}, } if err := yaml.Unmarshal([]byte(content), &m); err != nil { t.Fatal(err) } for _, s := range m.Steps { _, ok := s.Value.(map[string]interface{}) if !ok { t.Fatal("unexpected error") } } } }) } } func TestSameNameInineStruct(t *testing.T) { type X struct { X float64 `yaml:"x"` } type T struct { X `yaml:",inline"` } var v T if err := yaml.Unmarshal([]byte(`x: 0.7`), &v); err != nil { t.Fatal(err) } if fmt.Sprint(v.X.X) != "0.7" { t.Fatalf("failed to decode") } } type unmarshableMapKey struct { Key string } func (mk *unmarshableMapKey) UnmarshalYAML(b []byte) error { mk.Key = string(b) return nil } type testNodeUnmarshalerCtx struct { outErr error received ast.Node } func (u *testNodeUnmarshalerCtx) UnmarshalYAML(ctx context.Context, node ast.Node) error { if u.outErr != nil { return u.outErr } if ctx == nil { return errors.New("nil context") } u.received = node return nil } func TestNodeUnmarshalerContext(t *testing.T) { type testNodeUnmarshalerBody struct { Root testNodeUnmarshalerCtx `yaml:"root"` } cases := []struct { name string expectErr string src []string body testNodeUnmarshalerBody }{ { name: "should pass node", src: []string{ "root:", " foo: bar", " fizz: buzz", }, }, { name: "should pass returned error", body: testNodeUnmarshalerBody{ Root: testNodeUnmarshalerCtx{ outErr: errors.New("test error"), }, }, expectErr: "test error", src: []string{ "root:", " foo: bar", " fizz: buzz", }, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { src := []byte(strings.Join(c.src, "\n")) out := c.body err := yaml.Unmarshal(src, &out) if c.expectErr != "" { if err == nil { t.Fatal("expected error but got nil") return } if !strings.Contains(err.Error(), c.expectErr) { t.Fatalf("error message %q should contain %q", err.Error(), c.expectErr) } return } expect := struct { Root ast.Node `yaml:"root"` }{} if err := yaml.UnmarshalContext(context.TODO(), src, &expect); err != nil { t.Fatal("invalid test yaml:", err) return } if err != nil { t.Fatalf("unexpected error: %s", err) } if !reflect.DeepEqual(out.Root.received, expect.Root) { t.Fatalf("expected:\n%#v\n but got:\n%#v", expect.Root, out.Root.received) } }) } } type testNodeUnmarshaler struct { outErr error received ast.Node } func (u *testNodeUnmarshaler) UnmarshalYAML(node ast.Node) error { if u.outErr != nil { return u.outErr } u.received = node return nil } func TestNodeUnmarshaler(t *testing.T) { type testNodeUnmarshalerBody struct { Root testNodeUnmarshaler `yaml:"root"` } cases := []struct { name string expectErr string src []string body testNodeUnmarshalerBody }{ { name: "should pass node", src: []string{ "root:", " foo: bar", " fizz: buzz", }, }, { name: "should pass returned error", body: testNodeUnmarshalerBody{ Root: testNodeUnmarshaler{ outErr: errors.New("test error"), }, }, expectErr: "test error", src: []string{ "root:", " foo: bar", " fizz: buzz", }, }, } for _, c := range cases { t.Run(c.name, func(t *testing.T) { src := []byte(strings.Join(c.src, "\n")) out := c.body err := yaml.Unmarshal(src, &out) if c.expectErr != "" { if err == nil { t.Fatal("expected error but got nil") return } if !strings.Contains(err.Error(), c.expectErr) { t.Fatalf("error message %q should contain %q", err.Error(), c.expectErr) } return } expect := struct { Root ast.Node `yaml:"root"` }{} if err := yaml.Unmarshal(src, &expect); err != nil { t.Fatal("invalid test yaml:", err) return } if err != nil { t.Fatalf("unexpected error: %s", err) } if !reflect.DeepEqual(out.Root.received, expect.Root) { t.Fatalf("expected:\n%#v\n but got:\n%#v", expect.Root, out.Root.received) } }) } } func TestMapKeyCustomUnmarshaler(t *testing.T) { var m map[unmarshableMapKey]string if err := yaml.Unmarshal([]byte(`key: value`), &m); err != nil { t.Fatalf("failed to unmarshal %v", err) } if len(m) != 1 { t.Fatalf("expected 1 element in map, but got %d", len(m)) } val, ok := m[unmarshableMapKey{Key: "key"}] if !ok { t.Fatal("expected to have element 'key' in map") } if val != "value" { t.Fatalf("expected to have value \"value\", but got %q", val) } } type bytesUnmershalerWithMapAlias struct{} func (*bytesUnmershalerWithMapAlias) UnmarshalYAML(b []byte) error { expected := strings.TrimPrefix(` aaaaa: bbbbb: bar: - | foo bar - name: | foo bar `, "\n") if string(b) != expected { return fmt.Errorf("failed to decode: expected:\n[%s]\nbut got:\n[%s]\n", expected, string(b)) } return nil } func TestBytesUnmarshalerWithMapAlias(t *testing.T) { yml := ` x-foo: &data bar: - | foo bar - name: | foo bar foo: aaaaa: bbbbb: *data ` type T struct { Foo bytesUnmershalerWithMapAlias `yaml:"foo"` } var v T if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } } func TestBytesUnmarshalerWithEmptyValue(t *testing.T) { type T struct{} unmarshaler := func(dst *T, b []byte) error { var v any return yaml.Unmarshal(b, &v) } yml := ` map: &m {} seq: &seq [] foo: # comment bar: *m baz: *seq ` m := yaml.CommentMap{} var v T if err := yaml.UnmarshalWithOptions( []byte(yml), &v, yaml.CommentToMap(m), yaml.CustomUnmarshaler[T](unmarshaler), ); err != nil { t.Fatal(err) } if err := yaml.UnmarshalWithOptions( []byte(yml), &v, yaml.CustomUnmarshaler[T](unmarshaler), ); err != nil { t.Fatal(err) } } func TestIssue650(t *testing.T) { type Disk struct { Name string `yaml:"name"` Format *bool `yaml:"format"` } type Sample struct { Disks []Disk `yaml:"disks"` } unmarshalDisk := func(dst *Disk, b []byte) error { var s string if err := yaml.Unmarshal(b, &s); err == nil { *dst = Disk{Name: s} return nil } return yaml.Unmarshal(b, dst) } data := []byte(` disks: - name: foo format: true `) var sample Sample if err := yaml.UnmarshalWithOptions(data, &sample, yaml.CustomUnmarshaler[Disk](unmarshalDisk)); err != nil { t.Fatal(err) } } func TestBytesUnmarshalerWithLiteral(t *testing.T) { t.Run("map value", func(t *testing.T) { type Literal string unmarshalLit := func(dst *Literal, b []byte) error { var s string if err := yaml.Unmarshal(b, &s); err != nil { return err } *dst = Literal(s) return nil } data := []byte(` - name: | foo bar - name: | foo bar `) var v []map[string]Literal if err := yaml.UnmarshalWithOptions(data, &v, yaml.CustomUnmarshaler[Literal](unmarshalLit)); err != nil { t.Fatal(err) } if !reflect.DeepEqual(v, []map[string]Literal{{"name": "foo\n bar\n"}, {"name": "foo\nbar\n"}}) { t.Fatalf("failed to get decoded value. got: %q", v) } }) t.Run("sequence value", func(t *testing.T) { type Literal string unmarshalLit := func(dst *Literal, b []byte) error { var s string if err := yaml.Unmarshal(b, &s); err != nil { return err } *dst = Literal(s) return nil } data := []byte(` - | foo bar - | foo bar `) var v []Literal if err := yaml.UnmarshalWithOptions(data, &v, yaml.CustomUnmarshaler[Literal](unmarshalLit)); err != nil { t.Fatal(err) } if !reflect.DeepEqual(v, []Literal{"foo\n bar\n", "foo\nbar\n"}) { t.Fatalf("failed to get decoded value. got: %q", v) } }) } func TestDecoderPreservesDefaultValues(t *testing.T) { type nested struct { Val string `yaml:"val"` } type test struct { First string `yaml:"first"` Default nested `yaml:"nested"` } yml := ` first: "Test" nested: # Just some comment here # val: "default" ` v := test{Default: nested{Val: "default"}} if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } if v.Default.Val != "default" { t.Fatal("decoder doesn't preserve struct defaults") } } func TestDecodeError(t *testing.T) { tests := []struct { name string source string }{ { name: "duplicated map key name with anchor-alias", source: "&0: *0\n*0:\n*0:", }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { var v any if err := yaml.Unmarshal([]byte(test.source), &v); err == nil { t.Fatal("cannot catch decode error") } }) } } func TestIssue617(t *testing.T) { data := ` a: !Not [!Equals [!Ref foo, 'bar']] ` var v map[string][]any if err := yaml.Unmarshal([]byte(data), &v); err != nil { t.Fatal(err) } if !reflect.DeepEqual(v, map[string][]any{ "a": {[]any{"foo", "bar"}}, }) { t.Fatalf("found unexpected value: %v", v) } } type issue337Template struct{} func (i *issue337Template) UnmarshalYAML(b []byte) error { expected := strings.TrimPrefix(` | apiVersion: v1 kind: ConfigMap metadata: name: "abc" namespace: "abc" data: foo: FOO `, "\n") if !bytes.Equal(b, []byte(expected)) { return fmt.Errorf("expected:\n%s\nbut got:\n%s\n", expected, string(b)) } return nil } func TestIssue337(t *testing.T) { yml := ` releases: - name: foo chart: ./raw values: - templates: - | apiVersion: v1 kind: ConfigMap metadata: name: "abc" namespace: "abc" data: foo: FOO ` type Value struct { Templates []*issue337Template `yaml:"templates"` } type Release struct { Values []*Value `yaml:"values"` } var v struct { Releases []*Release `yaml:"releases"` } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } } func TestSetNullValue(t *testing.T) { tests := []struct { name string src string }{ { name: "empty document", src: "", }, { name: "null value", src: "null", }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { t.Run("set null", func(t *testing.T) { var v any v = 0x1 if err := yaml.Unmarshal([]byte(test.src), &v); err != nil { t.Fatal(err) } if v != nil { t.Fatal("failed to set nil value") } }) t.Run("invalid value", func(t *testing.T) { var v *struct{} if err := yaml.Unmarshal([]byte(test.src), v); err != nil { t.Fatal(err) } if v != nil { t.Fatal("failed to set nil value") } }) }) } } goccy-go-yaml-52dacb8/docs/000077500000000000000000000000001501576637100156165ustar00rootroot00000000000000goccy-go-yaml-52dacb8/docs/playground/000077500000000000000000000000001501576637100200025ustar00rootroot00000000000000goccy-go-yaml-52dacb8/docs/playground/.gitignore000066400000000000000000000000311501576637100217640ustar00rootroot00000000000000node_modules *.wasm dist goccy-go-yaml-52dacb8/docs/playground/.vite/000077500000000000000000000000001501576637100210275ustar00rootroot00000000000000goccy-go-yaml-52dacb8/docs/playground/.vite/deps/000077500000000000000000000000001501576637100217625ustar00rootroot00000000000000goccy-go-yaml-52dacb8/docs/playground/.vite/deps/_metadata.json000066400000000000000000000002221501576637100245700ustar00rootroot00000000000000{ "hash": "a456637e", "configHash": "358b79f2", "lockfileHash": "c66b5dca", "browserHash": "923911c5", "optimized": {}, "chunks": {} }goccy-go-yaml-52dacb8/docs/playground/.vite/deps/package.json000066400000000000000000000000271501576637100242470ustar00rootroot00000000000000{ "type": "module" } goccy-go-yaml-52dacb8/docs/playground/Makefile000066400000000000000000000003571501576637100214470ustar00rootroot00000000000000.PHONY: build build: build/wasm build/page .PHONY: build/wasm build/wasm: GOOS=js GOARCH=wasm go build -o src/yaml.wasm ./cmd/yaml .PHONY: build/page build/page: npm run build .PHONY: deps deps: npm ci .PHONY: dev dev: npm run dev goccy-go-yaml-52dacb8/docs/playground/README.md000066400000000000000000000003651501576637100212650ustar00rootroot00000000000000# Playground ## Architecture - Vite - React - TypeScript - WebWorker - WebAssembly - Built with Go - Components - [Monaco Editor](https://microsoft.github.io/monaco-editor/) - [Xterm.js](https://xtermjs.org/) - [MUI](https://mui.com/) goccy-go-yaml-52dacb8/docs/playground/cmd/000077500000000000000000000000001501576637100205455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/docs/playground/cmd/yaml/000077500000000000000000000000001501576637100215075ustar00rootroot00000000000000goccy-go-yaml-52dacb8/docs/playground/cmd/yaml/main.go000066400000000000000000000546731501576637100230010ustar00rootroot00000000000000//go:build js && wasm package main import ( "bytes" "context" "errors" "fmt" "io" "strings" "syscall/js" "github.com/goccy/go-graphviz" "github.com/goccy/go-json" "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/lexer" "github.com/goccy/go-yaml/parser" "github.com/goccy/go-yaml/token" ) func response(v any, err error) map[string]any { if err != nil { return map[string]any{ "error": err.Error(), } } return map[string]any{ "response": v, } } func decode(this js.Value, args []js.Value) any { v := args[0].String() b, err := Decode(v) if err != nil { return response(nil, err) } return response(string(b), nil) } func tokenize(this js.Value, args []js.Value) any { v := args[0].String() b, err := Tokenize(v) if err != nil { return response(nil, err) } return response(string(b), nil) } func parseGroup(this js.Value, args []js.Value) any { v := args[0].String() b, err := ParseGroup(v) if err != nil { return response(nil, err) } return response(string(b), nil) } func parse(this js.Value, args []js.Value) any { v := args[0].String() b, err := Parse(context.Background(), v) if err != nil { return response(nil, err) } return response(string(b), nil) } func Decode(v string) ([]byte, error) { var ret []string dec := yaml.NewDecoder(strings.NewReader(v)) for { var v any if err := dec.Decode(&v); err != nil { if err == io.EOF { break } return nil, errors.New(yaml.FormatError(err, true, true)) } got, err := json.MarshalIndentWithOption(v, "", " ", json.Colorize(json.DefaultColorScheme)) if err != nil { return nil, err } ret = append(ret, string(got)) } return []byte(strings.Join(ret, "\n")), nil } type Token struct { Type string `json:"type"` Value string `json:"value"` Origin string `json:"origin"` Error string `json:"error"` Line int `json:"line"` Column int `json:"column"` Offset int `json:"offset"` } func Tokenize(v string) ([]byte, error) { tks := lexer.Tokenize(v) ret := make([]*Token, 0, len(tks)) for _, tk := range tks { ret = append(ret, toToken(tk)) } b, err := json.Marshal(ret) if err != nil { return nil, err } return b, nil } func toToken(tk *token.Token) *Token { if tk == nil { return nil } return &Token{ Type: tk.Type.String(), Value: tk.Value, Origin: tk.Origin, Error: tk.Error, Line: tk.Position.Line, Column: tk.Position.Column, Offset: tk.Position.Offset, } } type GroupedToken struct { Token *Token `json:"token"` Group *TokenGroup `json:"group"` LineComment *Token `json:"lineComment"` } type TokenGroup struct { Type string `json:"type"` Tokens []*GroupedToken `json:"tokens"` } func toGroupedToken(tk *parser.Token) *GroupedToken { if tk == nil { return nil } return &GroupedToken{ Token: toToken(tk.Token), Group: toTokenGroup(tk.Group), LineComment: toToken(tk.LineComment), } } func toTokenGroup(g *parser.TokenGroup) *TokenGroup { if g == nil { return nil } tokens := make([]*GroupedToken, 0, len(g.Tokens)) for _, tk := range g.Tokens { tokens = append(tokens, toGroupedToken(tk)) } return &TokenGroup{ Type: g.Type.String(), Tokens: tokens, } } func ParseGroup(v string) ([]byte, error) { tks, err := parser.CreateGroupedTokens(lexer.Tokenize(v)) if err != nil { return nil, err } ret := make([]*GroupedToken, 0, len(tks)) for _, tk := range tks { ret = append(ret, toGroupedToken(tk)) } b, err := json.Marshal(ret) if err != nil { return nil, err } return b, nil } func Parse(ctx context.Context, v string) ([]byte, error) { gv, err := graphviz.New(ctx) if err != nil { return nil, err } file, err := parser.ParseBytes([]byte(v), parser.ParseComments) if err != nil { return nil, err } graph, err := gv.Graph() if err != nil { return nil, err } graph.SetCompound(true) defer func() { if err := graph.Close(); err != nil { panic(err) } gv.Close() }() renderer := &NodeRenderer{} if _, err := renderer.renderFile(graph, file); err != nil { return nil, err } var out bytes.Buffer if err := gv.Render(ctx, graph, graphviz.SVG, &out); err != nil { return nil, err } return out.Bytes(), nil } type NodeRenderer struct { id int edges []*Edge } type Edge struct { start *Node end *Node } type Node struct { graphName string node *graphviz.Node } func (r *NodeRenderer) createID() string { r.id++ return fmt.Sprint(r.id) } func (r *NodeRenderer) createNodeGraph(parent *graphviz.Graph, node any, name string) (*graphviz.Graph, error) { id := r.createID() sub, err := parent.CreateSubGraphByName("cluster" + id) if err != nil { return nil, err } sub.SetCompound(true) sub.SetLabel(name) sub.SetStyle(graphviz.FilledGraphStyle) sub.SetBackgroundColor("white") return sub, nil } func (r *NodeRenderer) createNode(graph *graphviz.Graph, name string) (*graphviz.Node, error) { node, err := graph.CreateNodeByName(r.createID()) if err != nil { return nil, err } node.SetLabel(name) node.SetStyle(graphviz.FilledNodeStyle) node.SetFillColor("white") return node, nil } func (r *NodeRenderer) createEdge(fromGraph *graphviz.Graph, fromNode *graphviz.Node, toGraph *graphviz.Graph) error { to, err := toGraph.FirstNode() if err != nil { return err } edge, err := fromGraph.CreateEdgeByName("", fromNode, to) if err != nil { return err } fromGraphName, err := fromGraph.Name() if err != nil { return err } toGraphName, err := toGraph.Name() if err != nil { return err } edge.SetLogicalTail(fromGraphName) edge.SetLogicalHead(toGraphName) edge.SetMinLen(2) return nil } func (r *NodeRenderer) renderFile(graph *graphviz.Graph, file *ast.File) (*graphviz.Graph, error) { fileGraph, err := r.createNodeGraph(graph, file, "FileNode") if err != nil { return nil, err } fileGraph.SetBackgroundColor("ivory") for idx, doc := range file.Docs { node, err := r.createNode(fileGraph, fmt.Sprintf("docs[%d]", idx)) if err != nil { return nil, err } docGraph, err := r.renderDocument(fileGraph, doc) if err != nil { return nil, err } if err := r.createEdge(fileGraph, node, docGraph); err != nil { return nil, err } } return fileGraph, nil } func (r *NodeRenderer) renderDocument(graph *graphviz.Graph, doc *ast.DocumentNode) (*graphviz.Graph, error) { docGraph, err := r.createNodeGraph(graph, doc, "DocumentNode") if err != nil { return nil, err } docGraph.SetBackgroundColor("mintcream") if err := r.renderToken(docGraph, doc.Start); err != nil { return nil, err } if err := r.renderToken(docGraph, doc.End); err != nil { return nil, err } body, err := r.createNode(docGraph, "body") if err != nil { return nil, err } bodyGraph, err := r.renderNode(docGraph, doc.Body) if err != nil { return nil, err } if err := r.createEdge(docGraph, body, bodyGraph); err != nil { return nil, err } return docGraph, nil } func (r *NodeRenderer) renderNode(graph *graphviz.Graph, node ast.Node) (*graphviz.Graph, error) { switch n := node.(type) { case *ast.MappingNode: return r.renderMappingNode(graph, n) case *ast.NullNode: return r.renderNullNode(graph, n) case *ast.IntegerNode: return r.renderIntegerNode(graph, n) case *ast.FloatNode: return r.renderFloatNode(graph, n) case *ast.StringNode: return r.renderStringNode(graph, n) case *ast.LiteralNode: return r.renderLiteralNode(graph, n) case *ast.MergeKeyNode: return r.renderMergeKeyNode(graph, n) case *ast.BoolNode: return r.renderBoolNode(graph, n) case *ast.InfinityNode: return r.renderInfinityNode(graph, n) case *ast.NanNode: return r.renderNaNNode(graph, n) case *ast.MappingKeyNode: return r.renderMappingKeyNode(graph, n) case *ast.SequenceNode: return r.renderSequenceNode(graph, n) case *ast.AnchorNode: return r.renderAnchorNode(graph, n) case *ast.AliasNode: return r.renderAliasNode(graph, n) case *ast.DirectiveNode: return r.renderDirectiveNode(graph, n) case *ast.TagNode: return r.renderTagNode(graph, n) case *ast.CommentNode: case *ast.CommentGroupNode: } return nil, fmt.Errorf("unexpected node type %T", node) } func (r *NodeRenderer) renderMappingNode(graph *graphviz.Graph, node *ast.MappingNode) (*graphviz.Graph, error) { mapGraph, err := r.createNodeGraph(graph, node, "MappingNode") if err != nil { return nil, err } mapGraph.SetBackgroundColor("honeydew") if err := r.renderPath(mapGraph, node.GetPath()); err != nil { return nil, err } if err := r.renderToken(mapGraph, node.Start); err != nil { return nil, err } if err := r.renderToken(mapGraph, node.End); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(mapGraph, node.GetComment(), yaml.CommentHeadPosition); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(mapGraph, node.FootComment, yaml.CommentFootPosition); err != nil { return nil, err } for idx, value := range node.Values { node, err := r.createNode(mapGraph, fmt.Sprintf("values[%d]", idx)) if err != nil { return nil, err } valueGraph, err := r.renderMappingValueNode(mapGraph, value) if err != nil { return nil, err } if err := r.createEdge(mapGraph, node, valueGraph); err != nil { return nil, err } } return mapGraph, nil } func (r *NodeRenderer) renderMappingValueNode(graph *graphviz.Graph, node *ast.MappingValueNode) (*graphviz.Graph, error) { valueGraph, err := r.createNodeGraph(graph, node, "MappingValueNode") if err != nil { return nil, err } valueGraph.SetBackgroundColor("seashell") if err := r.renderPath(valueGraph, node.GetPath()); err != nil { return nil, err } if err := r.renderToken(valueGraph, node.Start); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(valueGraph, node.GetComment(), yaml.CommentHeadPosition); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(valueGraph, node.FootComment, yaml.CommentFootPosition); err != nil { return nil, err } keyNode, err := r.createNode(valueGraph, "key") if err != nil { return nil, err } valueNode, err := r.createNode(valueGraph, "value") if err != nil { return nil, err } keyGraph, err := r.renderNode(valueGraph, node.Key) if err != nil { return nil, err } valueContentGraph, err := r.renderNode(valueGraph, node.Value) if err != nil { return nil, err } if err := r.createEdge(valueGraph, keyNode, keyGraph); err != nil { return nil, err } if err := r.createEdge(valueGraph, valueNode, valueContentGraph); err != nil { return nil, err } return valueGraph, nil } func (r *NodeRenderer) renderStringNode(graph *graphviz.Graph, n *ast.StringNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "StringNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("lavenderblush") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if err := r.renderToken(subGraph, n.Token); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderNullNode(graph *graphviz.Graph, n *ast.NullNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "NullNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("lavenderblush") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } if _, err := r.createNode(subGraph, "null"); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderIntegerNode(graph *graphviz.Graph, n *ast.IntegerNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "IntegerNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("lavenderblush") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } if _, err := r.createNode(subGraph, n.Token.Value); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderFloatNode(graph *graphviz.Graph, n *ast.FloatNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "FloatNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("lavenderblush") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.createNode(subGraph, n.Token.Value); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderLiteralNode(graph *graphviz.Graph, n *ast.LiteralNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "LiteralNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("beige") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } value, err := r.createNode(subGraph, "value") if err != nil { return nil, err } strGraph, err := r.renderStringNode(subGraph, n.Value) if err != nil { return nil, err } if err := r.createEdge(subGraph, value, strGraph); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderMergeKeyNode(graph *graphviz.Graph, n *ast.MergeKeyNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "MergeKeyNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("cornsilk") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentHeadPosition); err != nil { return nil, err } if _, err := r.createNode(subGraph, n.Token.Value); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderBoolNode(graph *graphviz.Graph, n *ast.BoolNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "BoolNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("lavenderblush") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } if _, err := r.createNode(subGraph, n.Token.Value); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderInfinityNode(graph *graphviz.Graph, n *ast.InfinityNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "InfinityNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("lavenderblush") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } if _, err := r.createNode(subGraph, n.Token.Value); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderNaNNode(graph *graphviz.Graph, n *ast.NanNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "NaNNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("lavenderblush") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } if _, err := r.createNode(subGraph, n.Token.Value); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderMappingKeyNode(graph *graphviz.Graph, n *ast.MappingKeyNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "MappingKeyNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("cornsilk") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentHeadPosition); err != nil { return nil, err } value, err := r.createNode(subGraph, "value") if err != nil { return nil, err } valueGraph, err := r.renderNode(subGraph, n.Value) if err != nil { return nil, err } if err := r.createEdge(subGraph, value, valueGraph); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderSequenceNode(graph *graphviz.Graph, n *ast.SequenceNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "SequenceNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("honeydew") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if err := r.renderToken(subGraph, n.Start); err != nil { return nil, err } if err := r.renderToken(subGraph, n.End); err != nil { return nil, err } for _, head := range n.ValueHeadComments { if _, err := r.renderCommentGroupNode(subGraph, head, yaml.CommentHeadPosition); err != nil { return nil, err } } if _, err := r.renderCommentGroupNode(subGraph, n.FootComment, yaml.CommentFootPosition); err != nil { return nil, err } for idx, value := range n.Values { node, err := r.createNode(subGraph, fmt.Sprintf("values[%d]", idx)) if err != nil { return nil, err } valueGraph, err := r.renderNode(subGraph, value) if err != nil { return nil, err } if err := r.createEdge(subGraph, node, valueGraph); err != nil { return nil, err } } return subGraph, nil } func (r *NodeRenderer) renderAnchorNode(graph *graphviz.Graph, n *ast.AnchorNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "AnchorNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("oldlace") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } if err := r.renderToken(subGraph, n.Start); err != nil { return nil, err } name, err := r.createNode(subGraph, "name") if err != nil { return nil, err } value, err := r.createNode(subGraph, "value") if err != nil { return nil, err } nameGraph, err := r.renderNode(subGraph, n.Name) if err != nil { return nil, err } valueGraph, err := r.renderNode(subGraph, n.Value) if err != nil { return nil, err } if err := r.createEdge(subGraph, name, nameGraph); err != nil { return nil, err } if err := r.createEdge(subGraph, value, valueGraph); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderAliasNode(graph *graphviz.Graph, n *ast.AliasNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "AliasNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("lavenderblush") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } if err := r.renderToken(subGraph, n.Start); err != nil { return nil, err } value, err := r.createNode(subGraph, "value") if err != nil { return nil, err } valueGraph, err := r.renderNode(subGraph, n.Value) if err != nil { return nil, err } if err := r.createEdge(subGraph, value, valueGraph); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderDirectiveNode(graph *graphviz.Graph, n *ast.DirectiveNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "DirectiveNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("snow") if err := r.renderToken(subGraph, n.Start); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } name, err := r.createNode(subGraph, "name") if err != nil { return nil, err } nameGraph, err := r.renderNode(subGraph, n.Name) if err != nil { return nil, err } if err := r.createEdge(subGraph, name, nameGraph); err != nil { return nil, err } for idx, value := range n.Values { val, err := r.createNode(subGraph, fmt.Sprintf("values[%d]", idx)) if err != nil { return nil, err } valGraph, err := r.renderNode(subGraph, value) if err != nil { return nil, err } if err := r.createEdge(subGraph, val, valGraph); err != nil { return nil, err } } return subGraph, nil } func (r *NodeRenderer) renderTagNode(graph *graphviz.Graph, n *ast.TagNode) (*graphviz.Graph, error) { subGraph, err := r.createNodeGraph(graph, n, "TagNode") if err != nil { return nil, err } subGraph.SetBackgroundColor("ghostwhite") if err := r.renderPath(subGraph, n.GetPath()); err != nil { return nil, err } if _, err := r.renderCommentGroupNode(subGraph, n.GetComment(), yaml.CommentLinePosition); err != nil { return nil, err } if err := r.renderToken(subGraph, n.Start); err != nil { return nil, err } value, err := r.createNode(subGraph, "value") if err != nil { return nil, err } valueGraph, err := r.renderNode(subGraph, n.Value) if err != nil { return nil, err } if err := r.createEdge(subGraph, value, valueGraph); err != nil { return nil, err } return subGraph, nil } func (r *NodeRenderer) renderCommentGroupNode(graph *graphviz.Graph, n *ast.CommentGroupNode, pos yaml.CommentPosition) (*graphviz.Graph, error) { if n == nil { return nil, nil } subGraph, err := r.createNodeGraph(graph, n, fmt.Sprintf("CommentGroupNode (%s)", pos)) if err != nil { return nil, err } subGraph.SetBackgroundColor("whitesmoke") for _, cm := range n.Comments { if err := r.renderToken(subGraph, cm.Token); err != nil { return nil, err } } return subGraph, nil } func (r *NodeRenderer) renderPath(graph *graphviz.Graph, p string) error { node, err := graph.CreateNodeByName(r.createID()) if err != nil { return err } node.SetLabel(fmt.Sprintf("{path|%s}", p)) node.SetShape("record") node.SetStyle(graphviz.FilledNodeStyle) node.SetFillColor("white") return nil } func (r *NodeRenderer) renderToken(graph *graphviz.Graph, tk *token.Token) error { if tk == nil { return nil } node, err := graph.CreateNodeByName(r.createID()) if err != nil { return err } pos := tk.Position node.SetLabel(fmt.Sprintf("{pos|%d:%d}|{value|%s}", pos.Line, pos.Column, tk.Value)) node.SetShape("record") node.SetStyle(graphviz.FilledNodeStyle) node.SetFillColor("white") return nil } func main() { js.Global().Set("decode", js.FuncOf(decode)) js.Global().Set("tokenize", js.FuncOf(tokenize)) js.Global().Set("parseGroup", js.FuncOf(parseGroup)) js.Global().Set("parse", js.FuncOf(parse)) <-make(chan struct{}) } goccy-go-yaml-52dacb8/docs/playground/eslint.config.js000066400000000000000000000013361501576637100231050ustar00rootroot00000000000000import js from '@eslint/js' import globals from 'globals' import reactHooks from 'eslint-plugin-react-hooks' import reactRefresh from 'eslint-plugin-react-refresh' import tseslint from 'typescript-eslint' export default tseslint.config( { ignores: ['dist'] }, { extends: [js.configs.recommended, ...tseslint.configs.recommended], files: ['**/*.{ts,tsx}'], languageOptions: { ecmaVersion: 2020, globals: globals.browser, }, plugins: { 'react-hooks': reactHooks, 'react-refresh': reactRefresh, }, rules: { ...reactHooks.configs.recommended.rules, 'react-refresh/only-export-components': [ 'warn', { allowConstantExport: true }, ], }, }, ) goccy-go-yaml-52dacb8/docs/playground/go.mod000066400000000000000000000012551501576637100211130ustar00rootroot00000000000000module demo go 1.22.8 require ( github.com/goccy/go-graphviz v0.2.10-0.20250109095217-4ceff9e58e1a github.com/goccy/go-json v0.10.4 github.com/goccy/go-yaml v1.15.13 ) require ( github.com/disintegration/imaging v1.6.2 // indirect github.com/flopp/go-findfont v0.1.0 // indirect github.com/fogleman/gg v1.3.0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/tetratelabs/wazero v1.8.1 // indirect golang.org/x/image v0.21.0 // indirect golang.org/x/text v0.19.0 // indirect ) replace github.com/goccy/go-yaml => ../../ replace github.com/flopp/go-findfont => github.com/goccy/go-findfont v0.0.0-20250109093214-c2e12b298c75 goccy-go-yaml-52dacb8/docs/playground/go.sum000066400000000000000000000043621501576637100211420ustar00rootroot00000000000000github.com/corona10/goimagehash v1.1.0 h1:teNMX/1e+Wn/AYSbLHX8mj+mF9r60R1kBeqE9MkoYwI= github.com/corona10/goimagehash v1.1.0/go.mod h1:VkvE0mLn84L4aF8vCb6mafVajEb6QYMHl2ZJLn0mOGI= github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/goccy/go-findfont v0.0.0-20250109093214-c2e12b298c75 h1:XIuIPArJ/7VuKj7uygrjl7yBYP+sTa58ljJzOxU4qDc= github.com/goccy/go-findfont v0.0.0-20250109093214-c2e12b298c75/go.mod h1:bBfDkbCgtwEhoHfxProwm41bZX3SAcOHZbgbillrYQs= github.com/goccy/go-graphviz v0.2.10-0.20250109095217-4ceff9e58e1a h1:xAEcKHIL4BB8ztdnQ8Tr0Bd9Qt/k0Ps6/CHEAlSNhUo= github.com/goccy/go-graphviz v0.2.10-0.20250109095217-4ceff9e58e1a/go.mod h1:0pcNDbqQkokzppSVae3PfFgsUkta30nkVUFOPGNE9wA= github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/tetratelabs/wazero v1.8.1 h1:NrcgVbWfkWvVc4UtT4LRLDf91PsOzDzefMdwhLfA550= github.com/tetratelabs/wazero v1.8.1/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s= golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= goccy-go-yaml-52dacb8/docs/playground/index.html000066400000000000000000000021601501576637100217760ustar00rootroot00000000000000 goccy/go-yaml Playground
goccy-go-yaml-52dacb8/docs/playground/package-lock.json000066400000000000000000007717761501576637100232470ustar00rootroot00000000000000{ "name": "playground", "version": "0.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "playground", "version": "0.0.0", "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", "@monaco-editor/react": "^4.6.0", "@mui/icons-material": "^6.3.1", "@mui/material": "^6.3.0", "@xterm/addon-fit": "^0.10.0", "json2mq": "^0.2.0", "monaco-editor": "^0.52.2", "react": "^18.3.1", "react-dom": "^18.3.1", "react-monaco-editor": "^0.56.2" }, "devDependencies": { "@eslint/js": "^9.17.0", "@types/golang-wasm-exec": "^1.15.2", "@types/json2mq": "^0.2.2", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@vitejs/plugin-react": "^4.3.4", "eslint": "^9.17.0", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.16", "globals": "^15.14.0", "typescript": "~5.6.2", "typescript-eslint": "^8.18.2", "vite": "^6.0.5", "vite-plugin-svgr": "^4.3.0" } }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.0", "@babel/generator": "^7.26.0", "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-module-transforms": "^7.26.0", "@babel/helpers": "^7.26.0", "@babel/parser": "^7.26.0", "@babel/template": "^7.25.9", "@babel/traverse": "^7.25.9", "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/babel" } }, "node_modules/@babel/generator": { "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", "dependencies": { "@babel/parser": "^7.26.3", "@babel/types": "^7.26.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.25.9", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dependencies": { "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9", "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-plugin-utils": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", "dev": true, "dependencies": { "@babel/template": "^7.26.9", "@babel/types": "^7.26.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", "dependencies": { "@babel/types": "^7.26.10" }, "bin": { "parser": "bin/babel-parser.js" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/plugin-transform-react-jsx-self": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-react-jsx-source": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/runtime": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { "version": "7.26.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/parser": "^7.26.9", "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { "version": "7.26.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.26.3", "@babel/parser": "^7.26.3", "@babel/template": "^7.25.9", "@babel/types": "^7.26.3", "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@emotion/babel-plugin": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", "@emotion/serialize": "^1.3.3", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", "stylis": "4.2.0" } }, "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "node_modules/@emotion/cache": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", "dependencies": { "@emotion/memoize": "^0.9.0", "@emotion/sheet": "^1.4.0", "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "stylis": "4.2.0" } }, "node_modules/@emotion/hash": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" }, "node_modules/@emotion/is-prop-valid": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", "dependencies": { "@emotion/memoize": "^0.9.0" } }, "node_modules/@emotion/memoize": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" }, "node_modules/@emotion/react": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", "@emotion/cache": "^11.14.0", "@emotion/serialize": "^1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { "react": ">=16.8.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true } } }, "node_modules/@emotion/serialize": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", "dependencies": { "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", "@emotion/unitless": "^0.10.0", "@emotion/utils": "^1.4.2", "csstype": "^3.0.2" } }, "node_modules/@emotion/sheet": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" }, "node_modules/@emotion/styled": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", "@emotion/is-prop-valid": "^1.3.0", "@emotion/serialize": "^1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", "@emotion/utils": "^1.4.2" }, "peerDependencies": { "@emotion/react": "^11.0.0-rc.0", "react": ">=16.8.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true } } }, "node_modules/@emotion/unitless": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==" }, "node_modules/@emotion/weak-memoize": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", "cpu": [ "ppc64" ], "dev": true, "optional": true, "os": [ "aix" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/android-arm": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", "cpu": [ "arm" ], "dev": true, "optional": true, "os": [ "android" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "android" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/android-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "android" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "darwin" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "darwin" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "freebsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "freebsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", "cpu": [ "arm" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", "cpu": [ "ia32" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", "cpu": [ "loong64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", "cpu": [ "mips64el" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", "cpu": [ "ppc64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", "cpu": [ "riscv64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", "cpu": [ "s390x" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "linux" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/netbsd-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "netbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "netbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/openbsd-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "openbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "openbsd" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "sunos" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "win32" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", "cpu": [ "ia32" ], "dev": true, "optional": true, "os": [ "win32" ], "engines": { "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "win32" ], "engines": { "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint-community/regexpp": { "version": "4.12.1", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/config-array": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", "dev": true, "dependencies": { "@eslint/object-schema": "^2.1.5", "debug": "^4.3.1", "minimatch": "^3.1.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.15" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/eslintrc": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@eslint/js": { "version": "9.17.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/object-schema": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", "dev": true, "dependencies": { "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { "version": "0.16.6", "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" }, "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, "engines": { "node": ">=18.18" }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "engines": { "node": ">=12.22" }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/retry": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "dev": true, "engines": { "node": ">=18.18" }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@monaco-editor/loader": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", "dependencies": { "state-local": "^1.0.6" }, "peerDependencies": { "monaco-editor": ">= 0.21.0 < 1" } }, "node_modules/@monaco-editor/react": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", "dependencies": { "@monaco-editor/loader": "^1.4.0" }, "peerDependencies": { "monaco-editor": ">= 0.25.0 < 1", "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/@mui/core-downloads-tracker": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.3.1.tgz", "integrity": "sha512-2OmnEyoHpj5//dJJpMuxOeLItCCHdf99pjMFfUFdBteCunAK9jW+PwEo4mtdGcLs7P+IgZ+85ypd52eY4AigoQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.3.1.tgz", "integrity": "sha512-nJmWj1PBlwS3t1PnoqcixIsftE+7xrW3Su7f0yrjPw4tVjYrgkhU0hrRp+OlURfZ3ptdSkoBkalee9Bhf1Erfw==", "dependencies": { "@babel/runtime": "^7.26.0" }, "engines": { "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@mui/material": "^6.3.1", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true } } }, "node_modules/@mui/material": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.3.1.tgz", "integrity": "sha512-ynG9ayhxgCsHJ/dtDcT1v78/r2GwQyP3E0hPz3GdPRl0uFJz/uUTtI5KFYwadXmbC+Uv3bfB8laZ6+Cpzh03gA==", "dependencies": { "@babel/runtime": "^7.26.0", "@mui/core-downloads-tracker": "^6.3.1", "@mui/system": "^6.3.1", "@mui/types": "^7.2.21", "@mui/utils": "^6.3.1", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1", "react-is": "^19.0.0", "react-transition-group": "^4.4.5" }, "engines": { "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", "@mui/material-pigment-css": "^6.3.1", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { "optional": true }, "@emotion/styled": { "optional": true }, "@mui/material-pigment-css": { "optional": true }, "@types/react": { "optional": true } } }, "node_modules/@mui/material/node_modules/react-is": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==" }, "node_modules/@mui/private-theming": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.3.1.tgz", "integrity": "sha512-g0u7hIUkmXmmrmmf5gdDYv9zdAig0KoxhIQn1JN8IVqApzf/AyRhH3uDGx5mSvs8+a1zb4+0W6LC260SyTTtdQ==", "dependencies": { "@babel/runtime": "^7.26.0", "@mui/utils": "^6.3.1", "prop-types": "^15.8.1" }, "engines": { "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true } } }, "node_modules/@mui/styled-engine": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.3.1.tgz", "integrity": "sha512-/7CC0d2fIeiUxN5kCCwYu4AWUDd9cCTxWCyo0v/Rnv6s8uk6hWgJC3VLZBoDENBHf/KjqDZuYJ2CR+7hD6QYww==", "dependencies": { "@babel/runtime": "^7.26.0", "@emotion/cache": "^11.13.5", "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { "optional": true }, "@emotion/styled": { "optional": true } } }, "node_modules/@mui/system": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.3.1.tgz", "integrity": "sha512-AwqQ3EAIT2np85ki+N15fF0lFXX1iFPqenCzVOSl3QXKy2eifZeGd9dGtt7pGMoFw5dzW4dRGGzRpLAq9rkl7A==", "dependencies": { "@babel/runtime": "^7.26.0", "@mui/private-theming": "^6.3.1", "@mui/styled-engine": "^6.3.1", "@mui/types": "^7.2.21", "@mui/utils": "^6.3.1", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@emotion/react": { "optional": true }, "@emotion/styled": { "optional": true }, "@types/react": { "optional": true } } }, "node_modules/@mui/types": { "version": "7.2.21", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.21.tgz", "integrity": "sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==", "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true } } }, "node_modules/@mui/utils": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.3.1.tgz", "integrity": "sha512-sjGjXAngoio6lniQZKJ5zGfjm+LD2wvLwco7FbKe1fu8A7VIFmz2SwkLb+MDPLNX1lE7IscvNNyh1pobtZg2tw==", "dependencies": { "@babel/runtime": "^7.26.0", "@mui/types": "^7.2.21", "@types/prop-types": "^15.7.14", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-is": "^19.0.0" }, "engines": { "node": ">=14.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true } } }, "node_modules/@mui/utils/node_modules/react-is": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==" }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { "node": ">= 8" } }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, "node_modules/@rollup/pluginutils": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", "dev": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "engines": { "node": ">=14.0.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "peerDependenciesMeta": { "rollup": { "optional": true } } }, "node_modules/@rollup/pluginutils/node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", "cpu": [ "arm" ], "dev": true, "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-freebsd-arm64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "freebsd" ] }, "node_modules/@rollup/rollup-freebsd-x64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "freebsd" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", "cpu": [ "arm" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", "cpu": [ "arm" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", "cpu": [ "loong64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", "cpu": [ "ppc64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", "cpu": [ "riscv64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", "cpu": [ "s390x" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", "cpu": [ "ia32" ], "dev": true, "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ "win32" ] }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", "dev": true, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", "dev": true, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", "dev": true, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", "dev": true, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@svgr/babel-plugin-svg-dynamic-title": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", "dev": true, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@svgr/babel-plugin-svg-em-dimensions": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", "dev": true, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@svgr/babel-plugin-transform-react-native-svg": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", "dev": true, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@svgr/babel-plugin-transform-svg-component": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", "dev": true, "engines": { "node": ">=12" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@svgr/babel-preset": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", "dev": true, "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", "@svgr/babel-plugin-transform-svg-component": "8.0.0" }, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/@svgr/core": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "dev": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", "camelcase": "^6.2.0", "cosmiconfig": "^8.1.3", "snake-case": "^3.0.4" }, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" } }, "node_modules/@svgr/core/node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/sponsors/d-fischer" }, "peerDependencies": { "typescript": ">=4.9.5" }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, "node_modules/@svgr/hast-util-to-babel-ast": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", "dev": true, "dependencies": { "@babel/types": "^7.21.3", "entities": "^4.4.0" }, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" } }, "node_modules/@svgr/plugin-jsx": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", "dev": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", "@svgr/hast-util-to-babel-ast": "8.0.0", "svg-parser": "^2.0.4" }, "engines": { "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { "@svgr/core": "*" } }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "node_modules/@types/babel__generator": { "version": "7.6.8", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { "version": "7.20.6", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, "dependencies": { "@babel/types": "^7.20.7" } }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/golang-wasm-exec": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/@types/golang-wasm-exec/-/golang-wasm-exec-1.15.2.tgz", "integrity": "sha512-NA77toY4yOiiV5foDVT/rfxmtoox7ASHqGs4Eek8xTMcKWwAhZLOD3SYfLQKq4P2jtOLQQkeISq3zSuQ1Y+apg==", "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/json2mq": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@types/json2mq/-/json2mq-0.2.2.tgz", "integrity": "sha512-JqJOjbozVUnL8yP1b3Mmn+P8QBcp67hZfgf+zZmrIatxWUlll/HQRaG7mCD57uni0mVAUTpdPe6nGuNXcl9Yrg==", "dev": true, "license": "MIT" }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "node_modules/@types/prop-types": { "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==" }, "node_modules/@types/react": { "version": "18.3.18", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "node_modules/@types/react-dom": { "version": "18.3.5", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", "dev": true, "peerDependencies": { "@types/react": "^18.0.0" } }, "node_modules/@types/react-transition-group": { "version": "4.4.12", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", "peerDependencies": { "@types/react": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.19.0.tgz", "integrity": "sha512-NggSaEZCdSrFddbctrVjkVZvFC6KGfKfNK0CU7mNK/iKHGKbzT4Wmgm08dKpcZECBu9f5FypndoMyRHkdqfT1Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.19.0", "@typescript-eslint/type-utils": "8.19.0", "@typescript-eslint/utils": "8.19.0", "@typescript-eslint/visitor-keys": "8.19.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/parser": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.19.0.tgz", "integrity": "sha512-6M8taKyOETY1TKHp0x8ndycipTVgmp4xtg5QpEZzXxDhNvvHOJi5rLRkLr8SK3jTgD5l4fTlvBiRdfsuWydxBw==", "dev": true, "dependencies": { "@typescript-eslint/scope-manager": "8.19.0", "@typescript-eslint/types": "8.19.0", "@typescript-eslint/typescript-estree": "8.19.0", "@typescript-eslint/visitor-keys": "8.19.0", "debug": "^4.3.4" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.19.0.tgz", "integrity": "sha512-hkoJiKQS3GQ13TSMEiuNmSCvhz7ujyqD1x3ShbaETATHrck+9RaDdUbt+osXaUuns9OFwrDTTrjtwsU8gJyyRA==", "dev": true, "dependencies": { "@typescript-eslint/types": "8.19.0", "@typescript-eslint/visitor-keys": "8.19.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/type-utils": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.19.0.tgz", "integrity": "sha512-TZs0I0OSbd5Aza4qAMpp1cdCYVnER94IziudE3JU328YUHgWu9gwiwhag+fuLeJ2LkWLXI+F/182TbG+JaBdTg==", "dev": true, "dependencies": { "@typescript-eslint/typescript-estree": "8.19.0", "@typescript-eslint/utils": "8.19.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/types": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.19.0.tgz", "integrity": "sha512-8XQ4Ss7G9WX8oaYvD4OOLCjIQYgRQxO+qCiR2V2s2GxI9AUpo7riNwo6jDhKtTcaJjT8PY54j2Yb33kWtSJsmA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.0.tgz", "integrity": "sha512-WW9PpDaLIFW9LCbucMSdYUuGeFUz1OkWYS/5fwZwTA+l2RwlWFdJvReQqMUMBw4yJWJOfqd7An9uwut2Oj8sLw==", "dev": true, "dependencies": { "@typescript-eslint/types": "8.19.0", "@typescript-eslint/visitor-keys": "8.19.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/@typescript-eslint/utils": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.0.tgz", "integrity": "sha512-PTBG+0oEMPH9jCZlfg07LCB2nYI0I317yyvXGfxnvGvw4SHIOuRnQ3kadyyXY6tGdChusIHIbM5zfIbp4M6tCg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.19.0", "@typescript-eslint/types": "8.19.0", "@typescript-eslint/typescript-estree": "8.19.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.0.tgz", "integrity": "sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w==", "dev": true, "dependencies": { "@typescript-eslint/types": "8.19.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@vitejs/plugin-react": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", "dev": true, "dependencies": { "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx-self": "^7.25.9", "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "node_modules/@xterm/addon-fit": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz", "integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==", "peerDependencies": { "@xterm/xterm": "^5.0.0" } }, "node_modules/@xterm/xterm": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", "peer": true }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", "resolve": "^1.19.0" }, "engines": { "node": ">=10", "npm": ">=6" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { "version": "4.24.3", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/browserslist" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" }, "engines": { "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "engines": { "node": ">=6" } }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/caniuse-lite": { "version": "1.0.30001690", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/browserslist" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ] }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { "node": ">=6" } }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "node_modules/cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" }, "engines": { "node": ">=10" } }, "node_modules/cosmiconfig/node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "engines": { "node": ">= 6" } }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" }, "engines": { "node": ">= 8" } }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dependencies": { "ms": "^2.1.3" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "node_modules/electron-to-chromium": { "version": "1.5.76", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz", "integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==", "dev": true }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, "engines": { "node": ">=0.12" }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/esbuild": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { "node": ">=18" }, "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.1", "@esbuild/android-arm": "0.25.1", "@esbuild/android-arm64": "0.25.1", "@esbuild/android-x64": "0.25.1", "@esbuild/darwin-arm64": "0.25.1", "@esbuild/darwin-x64": "0.25.1", "@esbuild/freebsd-arm64": "0.25.1", "@esbuild/freebsd-x64": "0.25.1", "@esbuild/linux-arm": "0.25.1", "@esbuild/linux-arm64": "0.25.1", "@esbuild/linux-ia32": "0.25.1", "@esbuild/linux-loong64": "0.25.1", "@esbuild/linux-mips64el": "0.25.1", "@esbuild/linux-ppc64": "0.25.1", "@esbuild/linux-riscv64": "0.25.1", "@esbuild/linux-s390x": "0.25.1", "@esbuild/linux-x64": "0.25.1", "@esbuild/netbsd-arm64": "0.25.1", "@esbuild/netbsd-x64": "0.25.1", "@esbuild/openbsd-arm64": "0.25.1", "@esbuild/openbsd-x64": "0.25.1", "@esbuild/sunos-x64": "0.25.1", "@esbuild/win32-arm64": "0.25.1", "@esbuild/win32-ia32": "0.25.1", "@esbuild/win32-x64": "0.25.1" } }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint": { "version": "9.17.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.9.0", "@eslint/eslintrc": "^3.2.0", "@eslint/js": "9.17.0", "@eslint/plugin-kit": "^0.2.3", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://eslint.org/donate" }, "peerDependencies": { "jiti": "*" }, "peerDependenciesMeta": { "jiti": { "optional": true } } }, "node_modules/eslint-plugin-react-hooks": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", "dev": true, "engines": { "node": ">=10" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "node_modules/eslint-plugin-react-refresh": { "version": "0.4.16", "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.16.tgz", "integrity": "sha512-slterMlxAhov/DZO8NScf6mEeMBBXodFUolijDvrtTxyezyLoTQaa73FyYus/VbTdftd8wBgBxPMRk3poleXNQ==", "dev": true, "peerDependencies": { "eslint": ">=8.40" } }, "node_modules/eslint-scope": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" }, "engines": { "node": ">=0.10" } }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" }, "engines": { "node": ">=8.6.0" } }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fastq": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "dev": true, "dependencies": { "reusify": "^1.0.4" } }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "dependencies": { "flat-cache": "^4.0.0" }, "engines": { "node": ">=16.0.0" } }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" }, "engines": { "node": ">=16" } }, "node_modules/flatted": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "dev": true }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { "is-glob": "^4.0.3" }, "engines": { "node": ">=10.13.0" } }, "node_modules/globals": { "version": "15.14.0", "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", "dev": true, "engines": { "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "dependencies": { "react-is": "^16.7.0" } }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { "node": ">=0.8.19" } }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "node_modules/is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dependencies": { "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "engines": { "node": ">=0.12.0" } }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "bin": { "jsesc": "bin/jsesc" }, "engines": { "node": ">=6" } }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/json2mq": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", "dependencies": { "string-convert": "^0.2.0" } }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" }, "engines": { "node": ">=6" } }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "dev": true, "dependencies": { "tslib": "^2.0.3" } }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { "yallist": "^3.0.2" } }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/monaco-editor": { "version": "0.52.2", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==" }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/nanoid": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.10.tgz", "integrity": "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], "bin": { "nanoid": "bin/nanoid.cjs" }, "engines": { "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dev": true, "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { "node": ">=0.10.0" } }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dependencies": { "callsites": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "engines": { "node": ">=8" } }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/postcss": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/postcss/" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-monaco-editor": { "version": "0.56.2", "resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.56.2.tgz", "integrity": "sha512-Tp5U3QF9h92Cuf0eIhGd8Jyef8tPMlEJC2Dk1GeuR/hj6WoFn8AgjVX/2dv+3l5DvpMUpAECcFarc3eFKTBZ5w==", "dependencies": { "prop-types": "^15.8.1" }, "peerDependencies": { "@types/react": ">=16 <= 18", "monaco-editor": "^0.52.0", "react": ">=16 <= 18" } }, "node_modules/react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", "prop-types": "^15.6.2" }, "peerDependencies": { "react": ">=16.6.0", "react-dom": ">=16.6.0" } }, "node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "engines": { "node": ">=4" } }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rollup": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz", "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==", "dev": true, "dependencies": { "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" }, "engines": { "node": ">=18.0.0", "npm": ">=8.0.0" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.35.0", "@rollup/rollup-android-arm64": "4.35.0", "@rollup/rollup-darwin-arm64": "4.35.0", "@rollup/rollup-darwin-x64": "4.35.0", "@rollup/rollup-freebsd-arm64": "4.35.0", "@rollup/rollup-freebsd-x64": "4.35.0", "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", "@rollup/rollup-linux-arm-musleabihf": "4.35.0", "@rollup/rollup-linux-arm64-gnu": "4.35.0", "@rollup/rollup-linux-arm64-musl": "4.35.0", "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", "@rollup/rollup-linux-riscv64-gnu": "4.35.0", "@rollup/rollup-linux-s390x-gnu": "4.35.0", "@rollup/rollup-linux-x64-gnu": "4.35.0", "@rollup/rollup-linux-x64-musl": "4.35.0", "@rollup/rollup-win32-arm64-msvc": "4.35.0", "@rollup/rollup-win32-ia32-msvc": "4.35.0", "@rollup/rollup-win32-x64-msvc": "4.35.0", "fsevents": "~2.3.2" } }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", "dev": true, "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/state-local": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" }, "node_modules/string-convert": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "engines": { "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/svg-parser": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", "dev": true }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/ts-api-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, "engines": { "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" } }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/typescript": { "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/typescript-eslint": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.19.0.tgz", "integrity": "sha512-Ni8sUkVWYK4KAcTtPjQ/UTiRk6jcsuDhPpxULapUDi8A/l8TSBk+t1GtJA1RsCzIJg0q6+J7bf35AwQigENWRQ==", "dev": true, "dependencies": { "@typescript-eslint/eslint-plugin": "8.19.0", "@typescript-eslint/parser": "8.19.0", "@typescript-eslint/utils": "8.19.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "node_modules/update-browserslist-db": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/browserslist" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" }, "peerDependencies": { "browserslist": ">= 4.21.0" } }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { "punycode": "^2.1.0" } }, "node_modules/vite": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz", "integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==", "dev": true, "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "bin": { "vite": "bin/vite.js" }, "engines": { "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, "jiti": { "optional": true }, "less": { "optional": true }, "lightningcss": { "optional": true }, "sass": { "optional": true }, "sass-embedded": { "optional": true }, "stylus": { "optional": true }, "sugarss": { "optional": true }, "terser": { "optional": true }, "tsx": { "optional": true }, "yaml": { "optional": true } } }, "node_modules/vite-plugin-svgr": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz", "integrity": "sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==", "dev": true, "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.1.3", "@svgr/core": "^8.1.0", "@svgr/plugin-jsx": "^8.1.0" }, "peerDependencies": { "vite": ">=2.6.0" } }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "node_modules/yaml": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, "optional": true, "peer": true, "bin": { "yaml": "bin.mjs" }, "engines": { "node": ">= 14" } }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } } }, "dependencies": { "@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "requires": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "@babel/compat-data": { "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", "dev": true }, "@babel/core": { "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.0", "@babel/generator": "^7.26.0", "@babel/helper-compilation-targets": "^7.25.9", "@babel/helper-module-transforms": "^7.26.0", "@babel/helpers": "^7.26.0", "@babel/parser": "^7.26.0", "@babel/template": "^7.25.9", "@babel/traverse": "^7.25.9", "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "@babel/generator": { "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", "requires": { "@babel/parser": "^7.26.3", "@babel/types": "^7.26.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "@babel/helper-compilation-targets": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, "requires": { "@babel/compat-data": "^7.25.9", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "@babel/helper-module-imports": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "requires": { "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" } }, "@babel/helper-module-transforms": { "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9", "@babel/traverse": "^7.25.9" } }, "@babel/helper-plugin-utils": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true }, "@babel/helper-string-parser": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==" }, "@babel/helper-validator-identifier": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==" }, "@babel/helper-validator-option": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true }, "@babel/helpers": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz", "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==", "dev": true, "requires": { "@babel/template": "^7.26.9", "@babel/types": "^7.26.10" } }, "@babel/parser": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz", "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==", "requires": { "@babel/types": "^7.26.10" } }, "@babel/plugin-transform-react-jsx-self": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.25.9" } }, "@babel/plugin-transform-react-jsx-source": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.25.9" } }, "@babel/runtime": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", "requires": { "regenerator-runtime": "^0.14.0" } }, "@babel/template": { "version": "7.26.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "requires": { "@babel/code-frame": "^7.26.2", "@babel/parser": "^7.26.9", "@babel/types": "^7.26.9" } }, "@babel/traverse": { "version": "7.26.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", "requires": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.26.3", "@babel/parser": "^7.26.3", "@babel/template": "^7.25.9", "@babel/types": "^7.26.3", "debug": "^4.3.1", "globals": "^11.1.0" }, "dependencies": { "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" } } }, "@babel/types": { "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz", "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==", "requires": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "@emotion/babel-plugin": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", "requires": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", "@emotion/serialize": "^1.3.3", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", "stylis": "4.2.0" }, "dependencies": { "convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" } } }, "@emotion/cache": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", "requires": { "@emotion/memoize": "^0.9.0", "@emotion/sheet": "^1.4.0", "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "stylis": "4.2.0" } }, "@emotion/hash": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" }, "@emotion/is-prop-valid": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", "requires": { "@emotion/memoize": "^0.9.0" } }, "@emotion/memoize": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" }, "@emotion/react": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "requires": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", "@emotion/cache": "^11.14.0", "@emotion/serialize": "^1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", "@emotion/utils": "^1.4.2", "@emotion/weak-memoize": "^0.4.0", "hoist-non-react-statics": "^3.3.1" } }, "@emotion/serialize": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", "requires": { "@emotion/hash": "^0.9.2", "@emotion/memoize": "^0.9.0", "@emotion/unitless": "^0.10.0", "@emotion/utils": "^1.4.2", "csstype": "^3.0.2" } }, "@emotion/sheet": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" }, "@emotion/styled": { "version": "11.14.0", "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", "requires": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", "@emotion/is-prop-valid": "^1.3.0", "@emotion/serialize": "^1.3.3", "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", "@emotion/utils": "^1.4.2" } }, "@emotion/unitless": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" }, "@emotion/use-insertion-effect-with-fallbacks": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", "requires": {} }, "@emotion/utils": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==" }, "@emotion/weak-memoize": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" }, "@esbuild/aix-ppc64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", "dev": true, "optional": true }, "@esbuild/android-arm": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", "dev": true, "optional": true }, "@esbuild/android-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", "dev": true, "optional": true }, "@esbuild/android-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", "dev": true, "optional": true }, "@esbuild/linux-arm": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", "dev": true, "optional": true }, "@esbuild/linux-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", "dev": true, "optional": true }, "@esbuild/netbsd-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", "dev": true, "optional": true }, "@esbuild/openbsd-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", "dev": true, "optional": true }, "@esbuild/win32-x64": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", "dev": true, "optional": true }, "@eslint-community/eslint-utils": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, "requires": { "eslint-visitor-keys": "^3.4.3" }, "dependencies": { "eslint-visitor-keys": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true } } }, "@eslint-community/regexpp": { "version": "4.12.1", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true }, "@eslint/config-array": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", "dev": true, "requires": { "@eslint/object-schema": "^2.1.5", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "@eslint/core": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", "dev": true, "requires": { "@types/json-schema": "^7.0.15" } }, "@eslint/eslintrc": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "dependencies": { "globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true } } }, "@eslint/js": { "version": "9.17.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", "dev": true }, "@eslint/object-schema": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", "dev": true }, "@eslint/plugin-kit": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", "dev": true, "requires": { "levn": "^0.4.1" } }, "@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true }, "@humanfs/node": { "version": "0.16.6", "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, "requires": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" }, "dependencies": { "@humanwhocodes/retry": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true } } }, "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true }, "@humanwhocodes/retry": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "dev": true }, "@jridgewell/gen-mapping": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "requires": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" }, "@jridgewell/set-array": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" }, "@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "requires": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@monaco-editor/loader": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", "requires": { "state-local": "^1.0.6" } }, "@monaco-editor/react": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", "requires": { "@monaco-editor/loader": "^1.4.0" } }, "@mui/core-downloads-tracker": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.3.1.tgz", "integrity": "sha512-2OmnEyoHpj5//dJJpMuxOeLItCCHdf99pjMFfUFdBteCunAK9jW+PwEo4mtdGcLs7P+IgZ+85ypd52eY4AigoQ==" }, "@mui/icons-material": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.3.1.tgz", "integrity": "sha512-nJmWj1PBlwS3t1PnoqcixIsftE+7xrW3Su7f0yrjPw4tVjYrgkhU0hrRp+OlURfZ3ptdSkoBkalee9Bhf1Erfw==", "requires": { "@babel/runtime": "^7.26.0" } }, "@mui/material": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.3.1.tgz", "integrity": "sha512-ynG9ayhxgCsHJ/dtDcT1v78/r2GwQyP3E0hPz3GdPRl0uFJz/uUTtI5KFYwadXmbC+Uv3bfB8laZ6+Cpzh03gA==", "requires": { "@babel/runtime": "^7.26.0", "@mui/core-downloads-tracker": "^6.3.1", "@mui/system": "^6.3.1", "@mui/types": "^7.2.21", "@mui/utils": "^6.3.1", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1", "react-is": "^19.0.0", "react-transition-group": "^4.4.5" }, "dependencies": { "react-is": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==" } } }, "@mui/private-theming": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.3.1.tgz", "integrity": "sha512-g0u7hIUkmXmmrmmf5gdDYv9zdAig0KoxhIQn1JN8IVqApzf/AyRhH3uDGx5mSvs8+a1zb4+0W6LC260SyTTtdQ==", "requires": { "@babel/runtime": "^7.26.0", "@mui/utils": "^6.3.1", "prop-types": "^15.8.1" } }, "@mui/styled-engine": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.3.1.tgz", "integrity": "sha512-/7CC0d2fIeiUxN5kCCwYu4AWUDd9cCTxWCyo0v/Rnv6s8uk6hWgJC3VLZBoDENBHf/KjqDZuYJ2CR+7hD6QYww==", "requires": { "@babel/runtime": "^7.26.0", "@emotion/cache": "^11.13.5", "@emotion/serialize": "^1.3.3", "@emotion/sheet": "^1.4.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" } }, "@mui/system": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.3.1.tgz", "integrity": "sha512-AwqQ3EAIT2np85ki+N15fF0lFXX1iFPqenCzVOSl3QXKy2eifZeGd9dGtt7pGMoFw5dzW4dRGGzRpLAq9rkl7A==", "requires": { "@babel/runtime": "^7.26.0", "@mui/private-theming": "^6.3.1", "@mui/styled-engine": "^6.3.1", "@mui/types": "^7.2.21", "@mui/utils": "^6.3.1", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" } }, "@mui/types": { "version": "7.2.21", "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.21.tgz", "integrity": "sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==", "requires": {} }, "@mui/utils": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.3.1.tgz", "integrity": "sha512-sjGjXAngoio6lniQZKJ5zGfjm+LD2wvLwco7FbKe1fu8A7VIFmz2SwkLb+MDPLNX1lE7IscvNNyh1pobtZg2tw==", "requires": { "@babel/runtime": "^7.26.0", "@mui/types": "^7.2.21", "@types/prop-types": "^15.7.14", "clsx": "^2.1.1", "prop-types": "^15.8.1", "react-is": "^19.0.0" }, "dependencies": { "react-is": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==" } } }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, "@rollup/pluginutils": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", "dev": true, "requires": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "dependencies": { "picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true } } }, "@rollup/rollup-android-arm-eabi": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz", "integrity": "sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==", "dev": true, "optional": true }, "@rollup/rollup-android-arm64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.35.0.tgz", "integrity": "sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==", "dev": true, "optional": true }, "@rollup/rollup-darwin-arm64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.35.0.tgz", "integrity": "sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==", "dev": true, "optional": true }, "@rollup/rollup-darwin-x64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.35.0.tgz", "integrity": "sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==", "dev": true, "optional": true }, "@rollup/rollup-freebsd-arm64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.35.0.tgz", "integrity": "sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==", "dev": true, "optional": true }, "@rollup/rollup-freebsd-x64": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.35.0.tgz", "integrity": "sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-gnueabihf": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.35.0.tgz", "integrity": "sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm-musleabihf": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.35.0.tgz", "integrity": "sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.35.0.tgz", "integrity": "sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==", "dev": true, "optional": true }, "@rollup/rollup-linux-arm64-musl": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.35.0.tgz", "integrity": "sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==", "dev": true, "optional": true }, "@rollup/rollup-linux-loongarch64-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.35.0.tgz", "integrity": "sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==", "dev": true, "optional": true }, "@rollup/rollup-linux-powerpc64le-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.35.0.tgz", "integrity": "sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==", "dev": true, "optional": true }, "@rollup/rollup-linux-riscv64-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.35.0.tgz", "integrity": "sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==", "dev": true, "optional": true }, "@rollup/rollup-linux-s390x-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.35.0.tgz", "integrity": "sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-gnu": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.35.0.tgz", "integrity": "sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==", "dev": true, "optional": true }, "@rollup/rollup-linux-x64-musl": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.35.0.tgz", "integrity": "sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==", "dev": true, "optional": true }, "@rollup/rollup-win32-arm64-msvc": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.35.0.tgz", "integrity": "sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==", "dev": true, "optional": true }, "@rollup/rollup-win32-ia32-msvc": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.35.0.tgz", "integrity": "sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==", "dev": true, "optional": true }, "@rollup/rollup-win32-x64-msvc": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.35.0.tgz", "integrity": "sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==", "dev": true, "optional": true }, "@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", "dev": true, "requires": {} }, "@svgr/babel-plugin-remove-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", "dev": true, "requires": {} }, "@svgr/babel-plugin-remove-jsx-empty-expression": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", "dev": true, "requires": {} }, "@svgr/babel-plugin-replace-jsx-attribute-value": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", "dev": true, "requires": {} }, "@svgr/babel-plugin-svg-dynamic-title": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", "dev": true, "requires": {} }, "@svgr/babel-plugin-svg-em-dimensions": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", "dev": true, "requires": {} }, "@svgr/babel-plugin-transform-react-native-svg": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", "dev": true, "requires": {} }, "@svgr/babel-plugin-transform-svg-component": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", "dev": true, "requires": {} }, "@svgr/babel-preset": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", "dev": true, "requires": { "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", "@svgr/babel-plugin-transform-svg-component": "8.0.0" } }, "@svgr/core": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "dev": true, "requires": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", "camelcase": "^6.2.0", "cosmiconfig": "^8.1.3", "snake-case": "^3.0.4" }, "dependencies": { "cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, "requires": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0", "path-type": "^4.0.0" } } } }, "@svgr/hast-util-to-babel-ast": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", "dev": true, "requires": { "@babel/types": "^7.21.3", "entities": "^4.4.0" } }, "@svgr/plugin-jsx": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", "dev": true, "requires": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", "@svgr/hast-util-to-babel-ast": "8.0.0", "svg-parser": "^2.0.4" } }, "@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "requires": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "@types/babel__generator": { "version": "7.6.8", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "@types/babel__traverse": { "version": "7.20.6", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, "requires": { "@babel/types": "^7.20.7" } }, "@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "@types/golang-wasm-exec": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/@types/golang-wasm-exec/-/golang-wasm-exec-1.15.2.tgz", "integrity": "sha512-NA77toY4yOiiV5foDVT/rfxmtoox7ASHqGs4Eek8xTMcKWwAhZLOD3SYfLQKq4P2jtOLQQkeISq3zSuQ1Y+apg==", "dev": true }, "@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "@types/json2mq": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@types/json2mq/-/json2mq-0.2.2.tgz", "integrity": "sha512-JqJOjbozVUnL8yP1b3Mmn+P8QBcp67hZfgf+zZmrIatxWUlll/HQRaG7mCD57uni0mVAUTpdPe6nGuNXcl9Yrg==", "dev": true }, "@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "@types/prop-types": { "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==" }, "@types/react": { "version": "18.3.18", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", "requires": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "@types/react-dom": { "version": "18.3.5", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", "dev": true, "requires": {} }, "@types/react-transition-group": { "version": "4.4.12", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", "requires": {} }, "@typescript-eslint/eslint-plugin": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.19.0.tgz", "integrity": "sha512-NggSaEZCdSrFddbctrVjkVZvFC6KGfKfNK0CU7mNK/iKHGKbzT4Wmgm08dKpcZECBu9f5FypndoMyRHkdqfT1Q==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.19.0", "@typescript-eslint/type-utils": "8.19.0", "@typescript-eslint/utils": "8.19.0", "@typescript-eslint/visitor-keys": "8.19.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/parser": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.19.0.tgz", "integrity": "sha512-6M8taKyOETY1TKHp0x8ndycipTVgmp4xtg5QpEZzXxDhNvvHOJi5rLRkLr8SK3jTgD5l4fTlvBiRdfsuWydxBw==", "dev": true, "requires": { "@typescript-eslint/scope-manager": "8.19.0", "@typescript-eslint/types": "8.19.0", "@typescript-eslint/typescript-estree": "8.19.0", "@typescript-eslint/visitor-keys": "8.19.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.19.0.tgz", "integrity": "sha512-hkoJiKQS3GQ13TSMEiuNmSCvhz7ujyqD1x3ShbaETATHrck+9RaDdUbt+osXaUuns9OFwrDTTrjtwsU8gJyyRA==", "dev": true, "requires": { "@typescript-eslint/types": "8.19.0", "@typescript-eslint/visitor-keys": "8.19.0" } }, "@typescript-eslint/type-utils": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.19.0.tgz", "integrity": "sha512-TZs0I0OSbd5Aza4qAMpp1cdCYVnER94IziudE3JU328YUHgWu9gwiwhag+fuLeJ2LkWLXI+F/182TbG+JaBdTg==", "dev": true, "requires": { "@typescript-eslint/typescript-estree": "8.19.0", "@typescript-eslint/utils": "8.19.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" } }, "@typescript-eslint/types": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.19.0.tgz", "integrity": "sha512-8XQ4Ss7G9WX8oaYvD4OOLCjIQYgRQxO+qCiR2V2s2GxI9AUpo7riNwo6jDhKtTcaJjT8PY54j2Yb33kWtSJsmA==", "dev": true }, "@typescript-eslint/typescript-estree": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.0.tgz", "integrity": "sha512-WW9PpDaLIFW9LCbucMSdYUuGeFUz1OkWYS/5fwZwTA+l2RwlWFdJvReQqMUMBw4yJWJOfqd7An9uwut2Oj8sLw==", "dev": true, "requires": { "@typescript-eslint/types": "8.19.0", "@typescript-eslint/visitor-keys": "8.19.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "dependencies": { "brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { "balanced-match": "^1.0.0" } }, "minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } }, "semver": { "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true } } }, "@typescript-eslint/utils": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.0.tgz", "integrity": "sha512-PTBG+0oEMPH9jCZlfg07LCB2nYI0I317yyvXGfxnvGvw4SHIOuRnQ3kadyyXY6tGdChusIHIbM5zfIbp4M6tCg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.19.0", "@typescript-eslint/types": "8.19.0", "@typescript-eslint/typescript-estree": "8.19.0" } }, "@typescript-eslint/visitor-keys": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.0.tgz", "integrity": "sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w==", "dev": true, "requires": { "@typescript-eslint/types": "8.19.0", "eslint-visitor-keys": "^4.2.0" } }, "@vitejs/plugin-react": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", "dev": true, "requires": { "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx-self": "^7.25.9", "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" } }, "@xterm/addon-fit": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz", "integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==", "requires": {} }, "@xterm/xterm": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", "peer": true }, "acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "requires": {} }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" } }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", "requires": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", "resolve": "^1.19.0" } }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { "fill-range": "^7.1.1" } }, "browserslist": { "version": "4.24.3", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", "dev": true, "requires": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" } }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "caniuse-lite": { "version": "1.0.30001690", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", "dev": true }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "cosmiconfig": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" }, "dependencies": { "yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" } } }, "cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "requires": { "ms": "^2.1.3" } }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", "requires": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, "requires": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "electron-to-chromium": { "version": "1.5.76", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz", "integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==", "dev": true }, "entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "requires": { "is-arrayish": "^0.2.1" } }, "esbuild": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", "dev": true, "requires": { "@esbuild/aix-ppc64": "0.25.1", "@esbuild/android-arm": "0.25.1", "@esbuild/android-arm64": "0.25.1", "@esbuild/android-x64": "0.25.1", "@esbuild/darwin-arm64": "0.25.1", "@esbuild/darwin-x64": "0.25.1", "@esbuild/freebsd-arm64": "0.25.1", "@esbuild/freebsd-x64": "0.25.1", "@esbuild/linux-arm": "0.25.1", "@esbuild/linux-arm64": "0.25.1", "@esbuild/linux-ia32": "0.25.1", "@esbuild/linux-loong64": "0.25.1", "@esbuild/linux-mips64el": "0.25.1", "@esbuild/linux-ppc64": "0.25.1", "@esbuild/linux-riscv64": "0.25.1", "@esbuild/linux-s390x": "0.25.1", "@esbuild/linux-x64": "0.25.1", "@esbuild/netbsd-arm64": "0.25.1", "@esbuild/netbsd-x64": "0.25.1", "@esbuild/openbsd-arm64": "0.25.1", "@esbuild/openbsd-x64": "0.25.1", "@esbuild/sunos-x64": "0.25.1", "@esbuild/win32-arm64": "0.25.1", "@esbuild/win32-ia32": "0.25.1", "@esbuild/win32-x64": "0.25.1" } }, "escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "eslint": { "version": "9.17.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.9.0", "@eslint/eslintrc": "^3.2.0", "@eslint/js": "9.17.0", "@eslint/plugin-kit": "^0.2.3", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" } }, "eslint-plugin-react-hooks": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", "dev": true, "requires": {} }, "eslint-plugin-react-refresh": { "version": "0.4.16", "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.16.tgz", "integrity": "sha512-slterMlxAhov/DZO8NScf6mEeMBBXodFUolijDvrtTxyezyLoTQaa73FyYus/VbTdftd8wBgBxPMRk3poleXNQ==", "dev": true, "requires": {} }, "eslint-scope": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "eslint-visitor-keys": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true }, "espree": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "requires": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "requires": { "estraverse": "^5.1.0" } }, "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { "estraverse": "^5.2.0" } }, "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, "estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" }, "dependencies": { "glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" } } } }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "dev": true, "requires": { "reusify": "^1.0.4" } }, "file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "requires": { "flat-cache": "^4.0.0" } }, "fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "requires": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "flatted": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "dev": true }, "fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "optional": true }, "function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { "is-glob": "^4.0.3" } }, "globals": { "version": "15.14.0", "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", "dev": true }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "requires": { "function-bind": "^1.1.2" } }, "hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "requires": { "react-is": "^16.7.0" } }, "ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-core-module": { "version": "2.16.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "requires": { "hasown": "^2.0.2" } }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { "argparse": "^2.0.1" } }, "jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==" }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json2mq": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", "requires": { "string-convert": "^0.2.0" } }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "requires": { "json-buffer": "3.0.1" } }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { "p-locate": "^5.0.0" } }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "dev": true, "requires": { "tslib": "^2.0.3" } }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "requires": { "yallist": "^3.0.2" } }, "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "requires": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "monaco-editor": { "version": "0.52.2", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==" }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "nanoid": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.10.tgz", "integrity": "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dev": true, "requires": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "requires": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { "yocto-queue": "^0.1.0" } }, "p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { "p-limit": "^3.0.2" } }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "requires": { "callsites": "^3.0.0" } }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, "picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "postcss": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "dev": true, "requires": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, "react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "requires": { "loose-envify": "^1.1.0" } }, "react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "requires": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" } }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-monaco-editor": { "version": "0.56.2", "resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.56.2.tgz", "integrity": "sha512-Tp5U3QF9h92Cuf0eIhGd8Jyef8tPMlEJC2Dk1GeuR/hj6WoFn8AgjVX/2dv+3l5DvpMUpAECcFarc3eFKTBZ5w==", "requires": { "prop-types": "^15.8.1" } }, "react-refresh": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "dev": true }, "react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", "requires": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", "prop-types": "^15.6.2" } }, "regenerator-runtime": { "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "requires": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, "rollup": { "version": "4.35.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.35.0.tgz", "integrity": "sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==", "dev": true, "requires": { "@rollup/rollup-android-arm-eabi": "4.35.0", "@rollup/rollup-android-arm64": "4.35.0", "@rollup/rollup-darwin-arm64": "4.35.0", "@rollup/rollup-darwin-x64": "4.35.0", "@rollup/rollup-freebsd-arm64": "4.35.0", "@rollup/rollup-freebsd-x64": "4.35.0", "@rollup/rollup-linux-arm-gnueabihf": "4.35.0", "@rollup/rollup-linux-arm-musleabihf": "4.35.0", "@rollup/rollup-linux-arm64-gnu": "4.35.0", "@rollup/rollup-linux-arm64-musl": "4.35.0", "@rollup/rollup-linux-loongarch64-gnu": "4.35.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.35.0", "@rollup/rollup-linux-riscv64-gnu": "4.35.0", "@rollup/rollup-linux-s390x-gnu": "4.35.0", "@rollup/rollup-linux-x64-gnu": "4.35.0", "@rollup/rollup-linux-x64-musl": "4.35.0", "@rollup/rollup-win32-arm64-msvc": "4.35.0", "@rollup/rollup-win32-ia32-msvc": "4.35.0", "@rollup/rollup-win32-x64-msvc": "4.35.0", "@types/estree": "1.0.6", "fsevents": "~2.3.2" } }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { "queue-microtask": "^1.2.2" } }, "scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "requires": { "loose-envify": "^1.1.0" } }, "semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { "shebang-regex": "^3.0.0" } }, "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", "dev": true, "requires": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" }, "source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true }, "state-local": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" }, "string-convert": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "stylis": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "svg-parser": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", "dev": true }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" } }, "ts-api-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, "requires": {} }, "tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { "prelude-ls": "^1.2.1" } }, "typescript": { "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true }, "typescript-eslint": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.19.0.tgz", "integrity": "sha512-Ni8sUkVWYK4KAcTtPjQ/UTiRk6jcsuDhPpxULapUDi8A/l8TSBk+t1GtJA1RsCzIJg0q6+J7bf35AwQigENWRQ==", "dev": true, "requires": { "@typescript-eslint/eslint-plugin": "8.19.0", "@typescript-eslint/parser": "8.19.0", "@typescript-eslint/utils": "8.19.0" } }, "update-browserslist-db": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "requires": { "escalade": "^3.2.0", "picocolors": "^1.1.0" } }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "vite": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz", "integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==", "dev": true, "requires": { "esbuild": "^0.25.0", "fsevents": "~2.3.3", "postcss": "^8.5.3", "rollup": "^4.30.1" } }, "vite-plugin-svgr": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.3.0.tgz", "integrity": "sha512-Jy9qLB2/PyWklpYy0xk0UU3TlU0t2UMpJXZvf+hWII1lAmRHrOUKi11Uw8N3rxoNk7atZNYO3pR3vI1f7oi+6w==", "dev": true, "requires": { "@rollup/pluginutils": "^5.1.3", "@svgr/core": "^8.1.0", "@svgr/plugin-jsx": "^8.1.0" } }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, "word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "yaml": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, "optional": true, "peer": true }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true } } } goccy-go-yaml-52dacb8/docs/playground/package.json000066400000000000000000000021071501576637100222700ustar00rootroot00000000000000{ "name": "playground", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview" }, "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", "@monaco-editor/react": "^4.6.0", "@mui/icons-material": "^6.3.1", "@mui/material": "^6.3.0", "@xterm/addon-fit": "^0.10.0", "json2mq": "^0.2.0", "monaco-editor": "^0.52.2", "react": "^18.3.1", "react-dom": "^18.3.1", "react-monaco-editor": "^0.56.2" }, "devDependencies": { "@eslint/js": "^9.17.0", "@types/golang-wasm-exec": "^1.15.2", "@types/json2mq": "^0.2.2", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@vitejs/plugin-react": "^4.3.4", "eslint": "^9.17.0", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.16", "globals": "^15.14.0", "typescript": "~5.6.2", "typescript-eslint": "^8.18.2", "vite": "^6.0.5", "vite-plugin-svgr": "^4.3.0" } } goccy-go-yaml-52dacb8/docs/playground/public/000077500000000000000000000000001501576637100212605ustar00rootroot00000000000000goccy-go-yaml-52dacb8/docs/playground/public/yaml.svg000066400000000000000000034752331501576637100227640ustar00rootroot00000000000000goccy-go-yaml-52dacb8/docs/playground/src/000077500000000000000000000000001501576637100205715ustar00rootroot00000000000000goccy-go-yaml-52dacb8/docs/playground/src/App.css000066400000000000000000000001011501576637100220130ustar00rootroot00000000000000#root { min-width: 300px; padding: 2rem; margin: 0 auto; } goccy-go-yaml-52dacb8/docs/playground/src/App.tsx000066400000000000000000000424011501576637100220520ustar00rootroot00000000000000import { AppBar, Toolbar, Typography, Box, Stack, SvgIcon, Button, TextField, Tabs, Tab, Tooltip, TooltipProps, tooltipClasses, styled, Snackbar, SnackbarCloseReason, IconButton } from '@mui/material'; import GitHub from '@mui/icons-material/GitHub'; import Share from '@mui/icons-material/Share'; import ContentCopy from '@mui/icons-material/ContentCopy'; import './App.css' import YAMLIcon from '/public/yaml.svg?react'; import React, { useState, useRef, useEffect } from 'react'; import { editor } from 'monaco-editor' import MonacoEditor, { loader } from '@monaco-editor/react'; import Grid from '@mui/material/Grid2'; import { FitAddon } from '@xterm/addon-fit'; import { Token, TokenGroup, GroupedToken, YAMLProcessResult, YAMLProcessResultType } from './YAML.ts'; import yamlWorker from "./worker?worker"; import '@xterm/xterm/css/xterm.css'; import { ArrowBackIosNew } from '@mui/icons-material' import { Terminal } from '@xterm/xterm'; import json2mq from 'json2mq'; import useMediaQuery from '@mui/material/useMediaQuery'; const themeBlack = '#313131'; const themeWhite = 'white'; const isXS = (): boolean => { const isNotXS = useMediaQuery( json2mq({ minWidth: 400, }) ); return !isNotXS; }; const contentHeight = (): number => { if (isXS()) { return 200; } return 400; } const Header = (content: any) => { const v = btoa(content.content as string); const shareURL = `${window.location.origin}${window.location.pathname}?content=${v}`; const [open, setOpen] = useState(false); const [shareURLFieldVisibility, setShareURLFieldVisibility] = useState('hidden'); return ( goccy/go-yaml Playground { if (reason === 'clickaway') { return; } setOpen(false); }} message="Copied" /> ) }; const Logo = () => { return ; } const ShareLink = (props: { setVisibility: React.Dispatch> }) => { const { setVisibility } = props; if (isXS()) { return ( { setVisibility('visible'); }}> ) } return ( ) } const GitHubLink = () => { if (isXS()) { return ( ) } return ( ) }; const TabPanel = (props: { children: any, value: number, index: number }) => { const { children, value, index, ...other } = props; return ( ); } const TerminalComponent = (v: any) => { const terminalRef = useRef(null) const [terminalInstance, setTerminalInstance] = useState(null) const fitAddon = new FitAddon(); const out = v.out; useEffect(() => { const instance = new Terminal({ cursorInactiveStyle: 'none', cursorStyle: 'bar', letterSpacing: 4, fontFamily: 'monospace', fontSize: 16, fontWeightBold: 'bold', convertEol: true, theme: { background: themeBlack, cursor: themeBlack, brightRed: '#da433a', }, }); instance.loadAddon(fitAddon); if (terminalRef.current) { instance.open(terminalRef.current) } setTerminalInstance(instance) return () => { instance.dispose() setTerminalInstance(null) } }, [ terminalRef, ]); useEffect(() => { if (!terminalInstance) { return; } terminalInstance.loadAddon(fitAddon); fitAddon.fit(); terminalInstance.clear(); terminalInstance.writeln(out); const handleResize = () => fitAddon.fit() window.addEventListener('resize', handleResize) return () => { window.removeEventListener('resize', handleResize); } }, [terminalRef, terminalInstance, out]); return ( ) } const CustomTooltip = styled(({ className, ...props }: TooltipProps) => ( ))({ [`& .${tooltipClasses.tooltip}`]: { fontSize: 16, whiteSpace: 'pre-wrap', }, }); const EmptyTokenContainer = () => { return ( ) }; const TokenContainer = ({ children }: { children: any }) => { return ( {children} ) }; const Lexer = (v: any) => { if (!v.tokens) { return } const tokens = v.tokens as Token[]; return ( <> { tokens.map((tk, idx) => { if (tokens.length > idx + 1) { return tokenToComponent(tk, tokens[idx + 1]); } return tokenToComponent(tk, null) }) } ) }; const groupedTokenToComponent = (g: GroupedToken, groups: string[]) => { if (g.token) { return tokenToComponentWithoutTip(g.token); } return groupTokenToComponent(g.group, groups); }; const tokenGroupToKey = (g: TokenGroup): string => { return g.type + g.tokens.map(tk => groupedTokenToKey(tk)).join('-'); }; const groupedTokenToKey = (g: GroupedToken): string => { if (g.group) { return tokenGroupToKey(g.group) } return `${g.token.offset}` } const groupTokenToComponent = (g: TokenGroup, groups: string[]) => { if (!g) { return <> } const groupColor = () => { switch (g.type) { case "directive": return "dimgray"; case "directive_name": return "orange" case "document": return "hotpink"; case "document_body": return "olive" case "anchor": return "deepskyblue"; case "anchor_name": return "brown" case "alias": return "limegreen"; case "literal": return "gold" case "folded": return "gold" case "scalar_tag": return "blueviolet"; case "map_key": return "coral"; case "map_key_value": return "teal" } return 'white'; } const newGroups = [...groups, g.type]; return ( ')} > { g.tokens.map(tk => { return groupedTokenToComponent(tk, newGroups); }) } ) }; const tokenToComponent = (tk: Token, nextTk: Token | null) => { if (!tk) { return <> } const orgs = tk.origin.split('\n').map((v, idx) => { if (idx > 0) { return ["\n", v]; } return v; }); const color = () => { if (nextTk && nextTk.type === 'MappingValue') { return '#008b8b'; } switch (tk.type) { case "String": return '#ff7f50'; } return 'black'; }; const prop = `type: ${tk.type} origin: ${JSON.stringify(tk.origin)} value: ${JSON.stringify(tk.value)} line: ${tk.line} column: ${tk.column} ` return ( { orgs.map((v, index) => { return ( {v} ) }) } ) }; const tokenToComponentWithoutTip = (tk: Token) => { if (!tk) { return <> } const orgs = tk.origin.split('\n').map((v, idx) => { if (idx > 0) { return ["\n", v]; } return v; }); return ( { orgs.map((v, index) => { return ( {v} ) }) } ) }; const ParserGroup = (v: any) => { if (!v.tokens) { return } const tokens = v.tokens as GroupedToken[]; return ( { tokens.map(tk => { return groupedTokenToComponent(tk, []); }) } ) }; const AST = (v: any) => { if (!v || !v.svg) { return } const parser = new DOMParser() const dom = parser.parseFromString(v.svg, 'text/xml'); const g = dom.getElementById('graph0'); if (!g) { return } const viewBox = g.parentElement!.getAttribute('viewBox')!; return ( ) } function App() { const [content, setContent] = useState(''); const editorRef = useRef(null); const workerRef = useRef(null); const [tokens, setTokens] = useState([]); const [groupedTokens, setGroupedTokens] = useState([]); const [out, setOut] = useState(''); const [svg, setSvg] = useState(''); const [tabIndex, setTabIndex] = useState(0); useEffect(() => { workerRef.current = new yamlWorker(); workerRef.current.onmessage = (event) => { const v = event.data as YAMLProcessResult; switch (v.type) { case YAMLProcessResultType.Decode: setOut(v.result as string); break; case YAMLProcessResultType.Lexer: if (typeof v.result === 'string') { console.error(v.result); } else { setTokens(v.result as Token[]); } break; case YAMLProcessResultType.ParserGroup: if (typeof v.result === 'string') { console.error(v.result); } else { setGroupedTokens(v.result as GroupedToken[]); } break; case YAMLProcessResultType.Parser: setSvg(v.result as string); break; default: break; } } return () => { workerRef.current?.terminate(); }; }, []); const onCodeChange = () => { if (!editorRef || !editorRef.current) { return } const code = editorRef.current.getValue()!; setContent(code); if (workerRef.current) { workerRef.current.postMessage({ code: code, tabIndex: tabIndex, }); } }; loader.init().then((monaco) => { monaco.editor.defineTheme('go-yaml-theme', { base: 'vs-dark', inherit: true, rules: [], colors: { 'editor.background': themeBlack, 'editor.selectionHighlightBorder': themeBlack, 'editor.lineHighlightBackground': themeBlack, 'editor.selectionBackground': themeBlack, }, }); }); const search = window.location.search; const yamlDataBinary = new URLSearchParams(search).get('content'); const onMount = (editor: editor.IStandaloneCodeEditor) => { editorRef.current = editor; if (yamlDataBinary) { const code = atob(yamlDataBinary) editor.setValue(code); setContent(code); if (workerRef.current) { workerRef.current.postMessage({ code: code, tabIndex: tabIndex, }); } } }; const onTabChange = (_: React.SyntheticEvent, newValue: number) => { setTabIndex(newValue); if (workerRef.current) { workerRef.current.postMessage({ code: content, tabIndex: newValue, }); } }; const tabProps = (index: number) => { return { id: `simple-tab-${index}`, 'aria-controls': `simple-tabpanel-${index}`, }; }; return ( <>
} iconPosition="end" style={{ marginLeft: 20 }} label="OUTPUT" {...tabProps(0)} /> } iconPosition="end" style={{ marginLeft: 0 }} label="AST" {...tabProps(1)} /> } iconPosition="end" style={{ marginLeft: 0 }} label="GROUPED TOKENS" {...tabProps(2)} /> ) } export default App goccy-go-yaml-52dacb8/docs/playground/src/YAML.ts000066400000000000000000000031161501576637100217040ustar00rootroot00000000000000import init from './yaml.wasm?init'; export interface GoValueType { response: string error: string } export interface YAMLGoFuncMap { decode: (v: string) => GoValueType; tokenize: (v: string) => GoValueType; parseGroup: (v: string) => GoValueType; parse: (v: string) => GoValueType; } export interface YAMLFuncMap { decode: (code: string) => Promise tokenize: (code: string) => Promise parseGroup: (code: string) => Promise parse: (code: string) => Promise } export enum YAMLProcessResultType { Decode, Lexer, ParserGroup, Parser, } export interface YAMLProcessResult { type: YAMLProcessResultType result: Token[] | GroupedToken[] | string } export interface Token { type: string value: string origin: string error: string line: number column: number offset: number } export interface GroupedToken { token: Token group: TokenGroup lineComment: Token } export interface TokenGroup { type: string tokens: GroupedToken[] } declare function decode(v: string): GoValueType; declare function tokenize(v: string): GoValueType; declare function parseGroup(v: string): GoValueType; declare function parse(v: string): GoValueType; export const initWASM = async (): Promise => { const go = new Go(); return new Promise(resolve => { init( go.importObject, ).then((instance) => { go.run(instance); resolve({ decode: decode, tokenize: tokenize, parseGroup: parseGroup, parse: parse, }); }); }); };goccy-go-yaml-52dacb8/docs/playground/src/index.css000066400000000000000000000002011501576637100224030ustar00rootroot00000000000000body { margin: 0; display: flex; place-items: center; min-width: 320px; min-height: 100vh; background-color: white; }goccy-go-yaml-52dacb8/docs/playground/src/main.tsx000066400000000000000000000003461501576637100222600ustar00rootroot00000000000000import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App.tsx' createRoot(document.getElementById('root')!).render( , ) goccy-go-yaml-52dacb8/docs/playground/src/vite-env.d.ts000066400000000000000000000001271501576637100231200ustar00rootroot00000000000000/// /// goccy-go-yaml-52dacb8/docs/playground/src/wasm_exec.js000066400000000000000000000411401501576637100231020ustar00rootroot00000000000000// Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. "use strict"; (() => { const enosys = () => { const err = new Error("not implemented"); err.code = "ENOSYS"; return err; }; if (!globalThis.fs) { let outputBuf = ""; globalThis.fs = { constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1, O_DIRECTORY: -1 }, // unused writeSync(fd, buf) { outputBuf += decoder.decode(buf); const nl = outputBuf.lastIndexOf("\n"); if (nl != -1) { console.log(outputBuf.substring(0, nl)); outputBuf = outputBuf.substring(nl + 1); } return buf.length; }, write(fd, buf, offset, length, position, callback) { if (offset !== 0 || length !== buf.length || position !== null) { callback(enosys()); return; } const n = this.writeSync(fd, buf); callback(null, n); }, chmod(path, mode, callback) { callback(enosys()); }, chown(path, uid, gid, callback) { callback(enosys()); }, close(fd, callback) { callback(enosys()); }, fchmod(fd, mode, callback) { callback(enosys()); }, fchown(fd, uid, gid, callback) { callback(enosys()); }, fstat(fd, callback) { callback(enosys()); }, fsync(fd, callback) { callback(null); }, ftruncate(fd, length, callback) { callback(enosys()); }, lchown(path, uid, gid, callback) { callback(enosys()); }, link(path, link, callback) { callback(enosys()); }, lstat(path, callback) { callback(enosys()); }, mkdir(path, perm, callback) { callback(enosys()); }, open(path, flags, mode, callback) { callback(enosys()); }, read(fd, buffer, offset, length, position, callback) { callback(enosys()); }, readdir(path, callback) { callback(enosys()); }, readlink(path, callback) { callback(enosys()); }, rename(from, to, callback) { callback(enosys()); }, rmdir(path, callback) { callback(enosys()); }, stat(path, callback) { callback(enosys()); }, symlink(path, link, callback) { callback(enosys()); }, truncate(path, length, callback) { callback(enosys()); }, unlink(path, callback) { callback(enosys()); }, utimes(path, atime, mtime, callback) { callback(enosys()); }, }; } if (!globalThis.process) { globalThis.process = { getuid() { return -1; }, getgid() { return -1; }, geteuid() { return -1; }, getegid() { return -1; }, getgroups() { throw enosys(); }, pid: -1, ppid: -1, umask() { throw enosys(); }, cwd() { throw enosys(); }, chdir() { throw enosys(); }, } } if (!globalThis.path) { globalThis.path = { resolve(...pathSegments) { return pathSegments.join("/"); } } } if (!globalThis.crypto) { throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)"); } if (!globalThis.performance) { throw new Error("globalThis.performance is not available, polyfill required (performance.now only)"); } if (!globalThis.TextEncoder) { throw new Error("globalThis.TextEncoder is not available, polyfill required"); } if (!globalThis.TextDecoder) { throw new Error("globalThis.TextDecoder is not available, polyfill required"); } const encoder = new TextEncoder("utf-8"); const decoder = new TextDecoder("utf-8"); globalThis.Go = class { constructor() { this.argv = ["js"]; this.env = {}; this.exit = (code) => { if (code !== 0) { console.warn("exit code:", code); } }; this._exitPromise = new Promise((resolve) => { this._resolveExitPromise = resolve; }); this._pendingEvent = null; this._scheduledTimeouts = new Map(); this._nextCallbackTimeoutID = 1; const setInt64 = (addr, v) => { this.mem.setUint32(addr + 0, v, true); this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true); } const setInt32 = (addr, v) => { this.mem.setUint32(addr + 0, v, true); } const getInt64 = (addr) => { const low = this.mem.getUint32(addr + 0, true); const high = this.mem.getInt32(addr + 4, true); return low + high * 4294967296; } const loadValue = (addr) => { const f = this.mem.getFloat64(addr, true); if (f === 0) { return undefined; } if (!isNaN(f)) { return f; } const id = this.mem.getUint32(addr, true); return this._values[id]; } const storeValue = (addr, v) => { const nanHead = 0x7FF80000; if (typeof v === "number" && v !== 0) { if (isNaN(v)) { this.mem.setUint32(addr + 4, nanHead, true); this.mem.setUint32(addr, 0, true); return; } this.mem.setFloat64(addr, v, true); return; } if (v === undefined) { this.mem.setFloat64(addr, 0, true); return; } let id = this._ids.get(v); if (id === undefined) { id = this._idPool.pop(); if (id === undefined) { id = this._values.length; } this._values[id] = v; this._goRefCounts[id] = 0; this._ids.set(v, id); } this._goRefCounts[id]++; let typeFlag = 0; switch (typeof v) { case "object": if (v !== null) { typeFlag = 1; } break; case "string": typeFlag = 2; break; case "symbol": typeFlag = 3; break; case "function": typeFlag = 4; break; } this.mem.setUint32(addr + 4, nanHead | typeFlag, true); this.mem.setUint32(addr, id, true); } const loadSlice = (addr) => { const array = getInt64(addr + 0); const len = getInt64(addr + 8); return new Uint8Array(this._inst.exports.mem.buffer, array, len); } const loadSliceOfValues = (addr) => { const array = getInt64(addr + 0); const len = getInt64(addr + 8); const a = new Array(len); for (let i = 0; i < len; i++) { a[i] = loadValue(array + i * 8); } return a; } const loadString = (addr) => { const saddr = getInt64(addr + 0); const len = getInt64(addr + 8); return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len)); } const testCallExport = (a, b) => { this._inst.exports.testExport0(); return this._inst.exports.testExport(a, b); } const timeOrigin = Date.now() - performance.now(); this.importObject = { _gotest: { add: (a, b) => a + b, callExport: testCallExport, }, gojs: { // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters) // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function). // This changes the SP, thus we have to update the SP used by the imported function. // func wasmExit(code int32) "runtime.wasmExit": (sp) => { sp >>>= 0; const code = this.mem.getInt32(sp + 8, true); this.exited = true; delete this._inst; delete this._values; delete this._goRefCounts; delete this._ids; delete this._idPool; this.exit(code); }, // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32) "runtime.wasmWrite": (sp) => { sp >>>= 0; const fd = getInt64(sp + 8); const p = getInt64(sp + 16); const n = this.mem.getInt32(sp + 24, true); fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n)); }, // func resetMemoryDataView() "runtime.resetMemoryDataView": (sp) => { sp >>>= 0; this.mem = new DataView(this._inst.exports.mem.buffer); }, // func nanotime1() int64 "runtime.nanotime1": (sp) => { sp >>>= 0; setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000); }, // func walltime() (sec int64, nsec int32) "runtime.walltime": (sp) => { sp >>>= 0; const msec = (new Date).getTime(); setInt64(sp + 8, msec / 1000); this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true); }, // func scheduleTimeoutEvent(delay int64) int32 "runtime.scheduleTimeoutEvent": (sp) => { sp >>>= 0; const id = this._nextCallbackTimeoutID; this._nextCallbackTimeoutID++; this._scheduledTimeouts.set(id, setTimeout( () => { this._resume(); while (this._scheduledTimeouts.has(id)) { // for some reason Go failed to register the timeout event, log and try again // (temporary workaround for https://github.com/golang/go/issues/28975) console.warn("scheduleTimeoutEvent: missed timeout event"); this._resume(); } }, getInt64(sp + 8), )); this.mem.setInt32(sp + 16, id, true); }, // func clearTimeoutEvent(id int32) "runtime.clearTimeoutEvent": (sp) => { sp >>>= 0; const id = this.mem.getInt32(sp + 8, true); clearTimeout(this._scheduledTimeouts.get(id)); this._scheduledTimeouts.delete(id); }, // func getRandomData(r []byte) "runtime.getRandomData": (sp) => { sp >>>= 0; crypto.getRandomValues(loadSlice(sp + 8)); }, // func finalizeRef(v ref) "syscall/js.finalizeRef": (sp) => { sp >>>= 0; const id = this.mem.getUint32(sp + 8, true); this._goRefCounts[id]--; if (this._goRefCounts[id] === 0) { const v = this._values[id]; this._values[id] = null; this._ids.delete(v); this._idPool.push(id); } }, // func stringVal(value string) ref "syscall/js.stringVal": (sp) => { sp >>>= 0; storeValue(sp + 24, loadString(sp + 8)); }, // func valueGet(v ref, p string) ref "syscall/js.valueGet": (sp) => { sp >>>= 0; const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16)); sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 32, result); }, // func valueSet(v ref, p string, x ref) "syscall/js.valueSet": (sp) => { sp >>>= 0; Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32)); }, // func valueDelete(v ref, p string) "syscall/js.valueDelete": (sp) => { sp >>>= 0; Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16)); }, // func valueIndex(v ref, i int) ref "syscall/js.valueIndex": (sp) => { sp >>>= 0; storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16))); }, // valueSetIndex(v ref, i int, x ref) "syscall/js.valueSetIndex": (sp) => { sp >>>= 0; Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24)); }, // func valueCall(v ref, m string, args []ref) (ref, bool) "syscall/js.valueCall": (sp) => { sp >>>= 0; try { const v = loadValue(sp + 8); const m = Reflect.get(v, loadString(sp + 16)); const args = loadSliceOfValues(sp + 32); const result = Reflect.apply(m, v, args); sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 56, result); this.mem.setUint8(sp + 64, 1); } catch (err) { sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 56, err); this.mem.setUint8(sp + 64, 0); } }, // func valueInvoke(v ref, args []ref) (ref, bool) "syscall/js.valueInvoke": (sp) => { sp >>>= 0; try { const v = loadValue(sp + 8); const args = loadSliceOfValues(sp + 16); const result = Reflect.apply(v, undefined, args); sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 40, result); this.mem.setUint8(sp + 48, 1); } catch (err) { sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 40, err); this.mem.setUint8(sp + 48, 0); } }, // func valueNew(v ref, args []ref) (ref, bool) "syscall/js.valueNew": (sp) => { sp >>>= 0; try { const v = loadValue(sp + 8); const args = loadSliceOfValues(sp + 16); const result = Reflect.construct(v, args); sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 40, result); this.mem.setUint8(sp + 48, 1); } catch (err) { sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 40, err); this.mem.setUint8(sp + 48, 0); } }, // func valueLength(v ref) int "syscall/js.valueLength": (sp) => { sp >>>= 0; setInt64(sp + 16, parseInt(loadValue(sp + 8).length)); }, // valuePrepareString(v ref) (ref, int) "syscall/js.valuePrepareString": (sp) => { sp >>>= 0; const str = encoder.encode(String(loadValue(sp + 8))); storeValue(sp + 16, str); setInt64(sp + 24, str.length); }, // valueLoadString(v ref, b []byte) "syscall/js.valueLoadString": (sp) => { sp >>>= 0; const str = loadValue(sp + 8); loadSlice(sp + 16).set(str); }, // func valueInstanceOf(v ref, t ref) bool "syscall/js.valueInstanceOf": (sp) => { sp >>>= 0; this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0); }, // func copyBytesToGo(dst []byte, src ref) (int, bool) "syscall/js.copyBytesToGo": (sp) => { sp >>>= 0; const dst = loadSlice(sp + 8); const src = loadValue(sp + 32); if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) { this.mem.setUint8(sp + 48, 0); return; } const toCopy = src.subarray(0, dst.length); dst.set(toCopy); setInt64(sp + 40, toCopy.length); this.mem.setUint8(sp + 48, 1); }, // func copyBytesToJS(dst ref, src []byte) (int, bool) "syscall/js.copyBytesToJS": (sp) => { sp >>>= 0; const dst = loadValue(sp + 8); const src = loadSlice(sp + 16); if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) { this.mem.setUint8(sp + 48, 0); return; } const toCopy = src.subarray(0, dst.length); dst.set(toCopy); setInt64(sp + 40, toCopy.length); this.mem.setUint8(sp + 48, 1); }, "debug": (value) => { console.log(value); }, } }; } async run(instance) { if (!(instance instanceof WebAssembly.Instance)) { throw new Error("Go.run: WebAssembly.Instance expected"); } this._inst = instance; this.mem = new DataView(this._inst.exports.mem.buffer); this._values = [ // JS values that Go currently has references to, indexed by reference id NaN, 0, null, true, false, globalThis, this, ]; this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id this._ids = new Map([ // mapping from JS values to reference ids [0, 1], [null, 2], [true, 3], [false, 4], [globalThis, 5], [this, 6], ]); this._idPool = []; // unused ids that have been garbage collected this.exited = false; // whether the Go program has exited // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory. let offset = 4096; const strPtr = (str) => { const ptr = offset; const bytes = encoder.encode(str + "\0"); new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes); offset += bytes.length; if (offset % 8 !== 0) { offset += 8 - (offset % 8); } return ptr; }; const argc = this.argv.length; const argvPtrs = []; this.argv.forEach((arg) => { argvPtrs.push(strPtr(arg)); }); argvPtrs.push(0); const keys = Object.keys(this.env).sort(); keys.forEach((key) => { argvPtrs.push(strPtr(`${key}=${this.env[key]}`)); }); argvPtrs.push(0); const argv = offset; argvPtrs.forEach((ptr) => { this.mem.setUint32(offset, ptr, true); this.mem.setUint32(offset + 4, 0, true); offset += 8; }); // The linker guarantees global data starts from at least wasmMinDataAddr. // Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr. const wasmMinDataAddr = 4096 + 8192; if (offset >= wasmMinDataAddr) { throw new Error("total length of command line and environment variables exceeds limit"); } this._inst.exports.run(argc, argv); if (this.exited) { this._resolveExitPromise(); } await this._exitPromise; } _resume() { if (this.exited) { throw new Error("Go program has already exited"); } this._inst.exports.resume(); if (this.exited) { this._resolveExitPromise(); } } _makeFuncWrapper(id) { const go = this; return function () { const event = { id: id, this: this, args: arguments }; go._pendingEvent = event; go._resume(); return event.result; }; } } })(); goccy-go-yaml-52dacb8/docs/playground/src/worker.ts000066400000000000000000000066461501576637100224660ustar00rootroot00000000000000import './wasm_exec'; import { YAMLFuncMap, YAMLProcessResultType, YAMLProcessResult, Token, GroupedToken, initWASM } from './YAML.ts'; const yaml = initWASM(); const funcMap = yaml.then((v): Promise => { const decode = (code: string): Promise => { return new Promise((resolve) => { const res = v.decode(code); if (res.error !== undefined) { resolve({ type: YAMLProcessResultType.Decode, result: res.error, }); return } resolve({ type: YAMLProcessResultType.Decode, result: res.response as string, }); }); }; const tokenize = (code: string): Promise => { return new Promise((resolve) => { const res = v.tokenize(code); if (res.error !== undefined) { resolve({ type: YAMLProcessResultType.Lexer, result: res.error, }); return } resolve({ type: YAMLProcessResultType.Lexer, result: JSON.parse(res.response) as Token[], }); }); }; const parseGroup = (code: string): Promise => { return new Promise((resolve) => { const res = v.parseGroup(code); if (res.error !== undefined) { resolve({ type: YAMLProcessResultType.ParserGroup, result: res.error, }); return } resolve({ type: YAMLProcessResultType.ParserGroup, result: JSON.parse(res.response) as GroupedToken[], }); }); }; const parse = (code: string): Promise => { return new Promise((resolve) => { const res = v.parse(code); if (res.error !== undefined) { resolve({ type: YAMLProcessResultType.Parser, result: res.error, }); return } resolve({ type: YAMLProcessResultType.Parser, result: res.response as string, }); }); }; return new Promise((resolve) => { resolve({ decode: decode, tokenize: tokenize, parseGroup: parseGroup, parse: parse, }); }) }); self.addEventListener('message', (e) => { const data = e.data as { code: string tabIndex: number } funcMap.then((v) => { switch (data.tabIndex) { case 0: v.decode(data.code).then((value) => { self.postMessage(value); }) break; case 1: v.parse(data.code).then((value) => { self.postMessage(value); }) break; case 2: v.parseGroup(data.code).then((value) => { self.postMessage(value); }) break; case 3: v.tokenize(data.code).then((value) => { self.postMessage(value); }) break; default: break; } }) }); export default {}goccy-go-yaml-52dacb8/docs/playground/tsconfig.app.json000066400000000000000000000012311501576637100232650ustar00rootroot00000000000000{ "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, "include": ["src"] } goccy-go-yaml-52dacb8/docs/playground/tsconfig.json000066400000000000000000000001671501576637100225150ustar00rootroot00000000000000{ "files": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ] } goccy-go-yaml-52dacb8/docs/playground/tsconfig.node.json000066400000000000000000000011211501576637100234300ustar00rootroot00000000000000{ "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", "lib": ["ES2023"], "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", "noEmit": true, /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, "include": ["vite.config.ts"] } goccy-go-yaml-52dacb8/docs/playground/vite.config.ts000066400000000000000000000003421501576637100225640ustar00rootroot00000000000000import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import svgr from 'vite-plugin-svgr' // https://vite.dev/config/ export default defineConfig({ base: '/go-yaml/', plugins: [react(), svgr()], }) goccy-go-yaml-52dacb8/encode.go000066400000000000000000000705421501576637100164620ustar00rootroot00000000000000package yaml import ( "context" "encoding" "fmt" "io" "math" "reflect" "sort" "strconv" "strings" "time" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" "github.com/goccy/go-yaml/parser" "github.com/goccy/go-yaml/printer" "github.com/goccy/go-yaml/token" ) const ( // DefaultIndentSpaces default number of space for indent DefaultIndentSpaces = 2 ) // Encoder writes YAML values to an output stream. type Encoder struct { writer io.Writer opts []EncodeOption singleQuote bool isFlowStyle bool isJSONStyle bool useJSONMarshaler bool enableSmartAnchor bool aliasRefToName map[uintptr]string anchorRefToName map[uintptr]string anchorNameMap map[string]struct{} anchorCallback func(*ast.AnchorNode, interface{}) error customMarshalerMap map[reflect.Type]func(context.Context, interface{}) ([]byte, error) omitZero bool omitEmpty bool autoInt bool useLiteralStyleIfMultiline bool commentMap map[*Path][]*Comment written bool line int column int offset int indentNum int indentLevel int indentSequence bool } // NewEncoder returns a new encoder that writes to w. // The Encoder should be closed after use to flush all data to w. func NewEncoder(w io.Writer, opts ...EncodeOption) *Encoder { return &Encoder{ writer: w, opts: opts, customMarshalerMap: map[reflect.Type]func(context.Context, interface{}) ([]byte, error){}, line: 1, column: 1, offset: 0, indentNum: DefaultIndentSpaces, anchorRefToName: make(map[uintptr]string), anchorNameMap: make(map[string]struct{}), aliasRefToName: make(map[uintptr]string), } } // Close closes the encoder by writing any remaining data. // It does not write a stream terminating string "...". func (e *Encoder) Close() error { return nil } // Encode writes the YAML encoding of v to the stream. // If multiple items are encoded to the stream, // the second and subsequent document will be preceded with a "---" document separator, // but the first will not. // // See the documentation for Marshal for details about the conversion of Go values to YAML. func (e *Encoder) Encode(v interface{}) error { return e.EncodeContext(context.Background(), v) } // EncodeContext writes the YAML encoding of v to the stream with context.Context. func (e *Encoder) EncodeContext(ctx context.Context, v interface{}) error { node, err := e.EncodeToNodeContext(ctx, v) if err != nil { return err } if err := e.setCommentByCommentMap(node); err != nil { return err } if !e.written { e.written = true } else { // write document separator _, _ = e.writer.Write([]byte("---\n")) } var p printer.Printer _, _ = e.writer.Write(p.PrintNode(node)) return nil } // EncodeToNode convert v to ast.Node. func (e *Encoder) EncodeToNode(v interface{}) (ast.Node, error) { return e.EncodeToNodeContext(context.Background(), v) } // EncodeToNodeContext convert v to ast.Node with context.Context. func (e *Encoder) EncodeToNodeContext(ctx context.Context, v interface{}) (ast.Node, error) { for _, opt := range e.opts { if err := opt(e); err != nil { return nil, err } } if e.enableSmartAnchor { // during the first encoding, store all mappings between alias addresses and their names. if _, err := e.encodeValue(ctx, reflect.ValueOf(v), 1); err != nil { return nil, err } e.clearSmartAnchorRef() } node, err := e.encodeValue(ctx, reflect.ValueOf(v), 1) if err != nil { return nil, err } return node, nil } func (e *Encoder) setCommentByCommentMap(node ast.Node) error { if e.commentMap == nil { return nil } for path, comments := range e.commentMap { n, err := path.FilterNode(node) if err != nil { return err } if n == nil { continue } for _, comment := range comments { commentTokens := []*token.Token{} for _, text := range comment.Texts { commentTokens = append(commentTokens, token.New(text, text, nil)) } commentGroup := ast.CommentGroup(commentTokens) switch comment.Position { case CommentHeadPosition: if err := e.setHeadComment(node, n, commentGroup); err != nil { return err } case CommentLinePosition: if err := e.setLineComment(node, n, commentGroup); err != nil { return err } case CommentFootPosition: if err := e.setFootComment(node, n, commentGroup); err != nil { return err } default: return ErrUnknownCommentPositionType } } } return nil } func (e *Encoder) setHeadComment(node ast.Node, filtered ast.Node, comment *ast.CommentGroupNode) error { parent := ast.Parent(node, filtered) if parent == nil { return ErrUnsupportedHeadPositionType(node) } switch p := parent.(type) { case *ast.MappingValueNode: if err := p.SetComment(comment); err != nil { return err } case *ast.MappingNode: if err := p.SetComment(comment); err != nil { return err } case *ast.SequenceNode: if len(p.ValueHeadComments) == 0 { p.ValueHeadComments = make([]*ast.CommentGroupNode, len(p.Values)) } var foundIdx int for idx, v := range p.Values { if v == filtered { foundIdx = idx break } } p.ValueHeadComments[foundIdx] = comment default: return ErrUnsupportedHeadPositionType(node) } return nil } func (e *Encoder) setLineComment(node ast.Node, filtered ast.Node, comment *ast.CommentGroupNode) error { switch filtered.(type) { case *ast.MappingValueNode, *ast.SequenceNode: // Line comment cannot be set for mapping value node. // It should probably be set for the parent map node if err := e.setLineCommentToParentMapNode(node, filtered, comment); err != nil { return err } default: if err := filtered.SetComment(comment); err != nil { return err } } return nil } func (e *Encoder) setLineCommentToParentMapNode(node ast.Node, filtered ast.Node, comment *ast.CommentGroupNode) error { parent := ast.Parent(node, filtered) if parent == nil { return ErrUnsupportedLinePositionType(node) } switch p := parent.(type) { case *ast.MappingValueNode: if err := p.Key.SetComment(comment); err != nil { return err } case *ast.MappingNode: if err := p.SetComment(comment); err != nil { return err } default: return ErrUnsupportedLinePositionType(parent) } return nil } func (e *Encoder) setFootComment(node ast.Node, filtered ast.Node, comment *ast.CommentGroupNode) error { parent := ast.Parent(node, filtered) if parent == nil { return ErrUnsupportedFootPositionType(node) } switch n := parent.(type) { case *ast.MappingValueNode: n.FootComment = comment case *ast.MappingNode: n.FootComment = comment case *ast.SequenceNode: n.FootComment = comment default: return ErrUnsupportedFootPositionType(n) } return nil } func (e *Encoder) encodeDocument(doc []byte) (ast.Node, error) { f, err := parser.ParseBytes(doc, 0) if err != nil { return nil, err } for _, docNode := range f.Docs { if docNode.Body != nil { return docNode.Body, nil } } return nil, nil } func (e *Encoder) isInvalidValue(v reflect.Value) bool { if !v.IsValid() { return true } kind := v.Type().Kind() if kind == reflect.Ptr && v.IsNil() { return true } if kind == reflect.Interface && v.IsNil() { return true } return false } type jsonMarshaler interface { MarshalJSON() ([]byte, error) } func (e *Encoder) existsTypeInCustomMarshalerMap(t reflect.Type) bool { if _, exists := e.customMarshalerMap[t]; exists { return true } globalCustomMarshalerMu.Lock() defer globalCustomMarshalerMu.Unlock() if _, exists := globalCustomMarshalerMap[t]; exists { return true } return false } func (e *Encoder) marshalerFromCustomMarshalerMap(t reflect.Type) (func(context.Context, interface{}) ([]byte, error), bool) { if marshaler, exists := e.customMarshalerMap[t]; exists { return marshaler, exists } globalCustomMarshalerMu.Lock() defer globalCustomMarshalerMu.Unlock() if marshaler, exists := globalCustomMarshalerMap[t]; exists { return marshaler, exists } return nil, false } func (e *Encoder) canEncodeByMarshaler(v reflect.Value) bool { if !v.CanInterface() { return false } if e.existsTypeInCustomMarshalerMap(v.Type()) { return true } iface := v.Interface() switch iface.(type) { case BytesMarshalerContext: return true case BytesMarshaler: return true case InterfaceMarshalerContext: return true case InterfaceMarshaler: return true case time.Time, *time.Time: return true case time.Duration: return true case encoding.TextMarshaler: return true case jsonMarshaler: return e.useJSONMarshaler } return false } func (e *Encoder) encodeByMarshaler(ctx context.Context, v reflect.Value, column int) (ast.Node, error) { iface := v.Interface() if marshaler, exists := e.marshalerFromCustomMarshalerMap(v.Type()); exists { doc, err := marshaler(ctx, iface) if err != nil { return nil, err } node, err := e.encodeDocument(doc) if err != nil { return nil, err } return node, nil } if marshaler, ok := iface.(BytesMarshalerContext); ok { doc, err := marshaler.MarshalYAML(ctx) if err != nil { return nil, err } node, err := e.encodeDocument(doc) if err != nil { return nil, err } return node, nil } if marshaler, ok := iface.(BytesMarshaler); ok { doc, err := marshaler.MarshalYAML() if err != nil { return nil, err } node, err := e.encodeDocument(doc) if err != nil { return nil, err } return node, nil } if marshaler, ok := iface.(InterfaceMarshalerContext); ok { marshalV, err := marshaler.MarshalYAML(ctx) if err != nil { return nil, err } return e.encodeValue(ctx, reflect.ValueOf(marshalV), column) } if marshaler, ok := iface.(InterfaceMarshaler); ok { marshalV, err := marshaler.MarshalYAML() if err != nil { return nil, err } return e.encodeValue(ctx, reflect.ValueOf(marshalV), column) } if t, ok := iface.(time.Time); ok { return e.encodeTime(t, column), nil } // Handle *time.Time explicitly since it implements TextMarshaler and shouldn't be treated as plain text if t, ok := iface.(*time.Time); ok && t != nil { return e.encodeTime(*t, column), nil } if t, ok := iface.(time.Duration); ok { return e.encodeDuration(t, column), nil } if marshaler, ok := iface.(encoding.TextMarshaler); ok { text, err := marshaler.MarshalText() if err != nil { return nil, err } node := e.encodeString(string(text), column) return node, nil } if e.useJSONMarshaler { if marshaler, ok := iface.(jsonMarshaler); ok { jsonBytes, err := marshaler.MarshalJSON() if err != nil { return nil, err } doc, err := JSONToYAML(jsonBytes) if err != nil { return nil, err } node, err := e.encodeDocument(doc) if err != nil { return nil, err } return node, nil } } return nil, errors.New("does not implemented Marshaler") } func (e *Encoder) encodeValue(ctx context.Context, v reflect.Value, column int) (ast.Node, error) { if e.isInvalidValue(v) { return e.encodeNil(), nil } if e.canEncodeByMarshaler(v) { node, err := e.encodeByMarshaler(ctx, v, column) if err != nil { return nil, err } return node, nil } switch v.Type().Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return e.encodeInt(v.Int()), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return e.encodeUint(v.Uint()), nil case reflect.Float32: return e.encodeFloat(v.Float(), 32), nil case reflect.Float64: return e.encodeFloat(v.Float(), 64), nil case reflect.Ptr: if value := e.encodePtrAnchor(v, column); value != nil { return value, nil } return e.encodeValue(ctx, v.Elem(), column) case reflect.Interface: return e.encodeValue(ctx, v.Elem(), column) case reflect.String: return e.encodeString(v.String(), column), nil case reflect.Bool: return e.encodeBool(v.Bool()), nil case reflect.Slice: if mapSlice, ok := v.Interface().(MapSlice); ok { return e.encodeMapSlice(ctx, mapSlice, column) } if value := e.encodePtrAnchor(v, column); value != nil { return value, nil } return e.encodeSlice(ctx, v) case reflect.Array: return e.encodeArray(ctx, v) case reflect.Struct: if v.CanInterface() { if mapItem, ok := v.Interface().(MapItem); ok { return e.encodeMapItem(ctx, mapItem, column) } if t, ok := v.Interface().(time.Time); ok { return e.encodeTime(t, column), nil } } return e.encodeStruct(ctx, v, column) case reflect.Map: if value := e.encodePtrAnchor(v, column); value != nil { return value, nil } return e.encodeMap(ctx, v, column) default: return nil, fmt.Errorf("unknown value type %s", v.Type().String()) } } func (e *Encoder) encodePtrAnchor(v reflect.Value, column int) ast.Node { anchorName, exists := e.getAnchor(v.Pointer()) if !exists { return nil } aliasName := anchorName alias := ast.Alias(token.New("*", "*", e.pos(column))) alias.Value = ast.String(token.New(aliasName, aliasName, e.pos(column))) e.setSmartAlias(aliasName, v.Pointer()) return alias } func (e *Encoder) pos(column int) *token.Position { return &token.Position{ Line: e.line, Column: column, Offset: e.offset, IndentNum: e.indentNum, IndentLevel: e.indentLevel, } } func (e *Encoder) encodeNil() *ast.NullNode { value := "null" return ast.Null(token.New(value, value, e.pos(e.column))) } func (e *Encoder) encodeInt(v int64) *ast.IntegerNode { value := strconv.FormatInt(v, 10) return ast.Integer(token.New(value, value, e.pos(e.column))) } func (e *Encoder) encodeUint(v uint64) *ast.IntegerNode { value := strconv.FormatUint(v, 10) return ast.Integer(token.New(value, value, e.pos(e.column))) } func (e *Encoder) encodeFloat(v float64, bitSize int) ast.Node { if v == math.Inf(0) { value := ".inf" return ast.Infinity(token.New(value, value, e.pos(e.column))) } else if v == math.Inf(-1) { value := "-.inf" return ast.Infinity(token.New(value, value, e.pos(e.column))) } else if math.IsNaN(v) { value := ".nan" return ast.Nan(token.New(value, value, e.pos(e.column))) } value := strconv.FormatFloat(v, 'g', -1, bitSize) if !strings.Contains(value, ".") && !strings.Contains(value, "e") { if e.autoInt { return ast.Integer(token.New(value, value, e.pos(e.column))) } // append x.0 suffix to keep float value context value = fmt.Sprintf("%s.0", value) } return ast.Float(token.New(value, value, e.pos(e.column))) } func (e *Encoder) isNeedQuoted(v string) bool { if e.isJSONStyle { return true } if e.useLiteralStyleIfMultiline && strings.ContainsAny(v, "\n\r") { return false } if e.isFlowStyle && strings.ContainsAny(v, `]},'"`) { return true } if e.isFlowStyle { for i := 0; i < len(v); i++ { if v[i] != ':' { continue } if i+1 < len(v) && v[i+1] == '/' { continue } return true } } if token.IsNeedQuoted(v) { return true } return false } func (e *Encoder) encodeString(v string, column int) *ast.StringNode { if e.isNeedQuoted(v) { if e.singleQuote { v = quoteWith(v, '\'') } else { v = strconv.Quote(v) } } return ast.String(token.New(v, v, e.pos(column))) } func (e *Encoder) encodeBool(v bool) *ast.BoolNode { value := strconv.FormatBool(v) return ast.Bool(token.New(value, value, e.pos(e.column))) } func (e *Encoder) encodeSlice(ctx context.Context, value reflect.Value) (*ast.SequenceNode, error) { if e.indentSequence { e.column += e.indentNum defer func() { e.column -= e.indentNum }() } column := e.column sequence := ast.Sequence(token.New("-", "-", e.pos(column)), e.isFlowStyle) for i := 0; i < value.Len(); i++ { node, err := e.encodeValue(ctx, value.Index(i), column) if err != nil { return nil, err } sequence.Values = append(sequence.Values, node) } return sequence, nil } func (e *Encoder) encodeArray(ctx context.Context, value reflect.Value) (*ast.SequenceNode, error) { if e.indentSequence { e.column += e.indentNum defer func() { e.column -= e.indentNum }() } column := e.column sequence := ast.Sequence(token.New("-", "-", e.pos(column)), e.isFlowStyle) for i := 0; i < value.Len(); i++ { node, err := e.encodeValue(ctx, value.Index(i), column) if err != nil { return nil, err } sequence.Values = append(sequence.Values, node) } return sequence, nil } func (e *Encoder) encodeMapItem(ctx context.Context, item MapItem, column int) (*ast.MappingValueNode, error) { k := reflect.ValueOf(item.Key) v := reflect.ValueOf(item.Value) value, err := e.encodeValue(ctx, v, column) if err != nil { return nil, err } if e.isMapNode(value) { value.AddColumn(e.indentNum) } if e.isTagAndMapNode(value) { value.AddColumn(e.indentNum) } return ast.MappingValue( token.New("", "", e.pos(column)), e.encodeString(k.Interface().(string), column), value, ), nil } func (e *Encoder) encodeMapSlice(ctx context.Context, value MapSlice, column int) (*ast.MappingNode, error) { node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle) for _, item := range value { encoded, err := e.encodeMapItem(ctx, item, column) if err != nil { return nil, err } node.Values = append(node.Values, encoded) } return node, nil } func (e *Encoder) isMapNode(node ast.Node) bool { _, ok := node.(ast.MapNode) return ok } func (e *Encoder) isTagAndMapNode(node ast.Node) bool { tn, ok := node.(*ast.TagNode) return ok && e.isMapNode(tn.Value) } func (e *Encoder) encodeMap(ctx context.Context, value reflect.Value, column int) (ast.Node, error) { node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle) keys := make([]interface{}, len(value.MapKeys())) for i, k := range value.MapKeys() { keys[i] = k.Interface() } sort.Slice(keys, func(i, j int) bool { return fmt.Sprint(keys[i]) < fmt.Sprint(keys[j]) }) for _, key := range keys { k := reflect.ValueOf(key) v := value.MapIndex(k) encoded, err := e.encodeValue(ctx, v, column) if err != nil { return nil, err } if e.isMapNode(encoded) { encoded.AddColumn(e.indentNum) } if e.isTagAndMapNode(encoded) { encoded.AddColumn(e.indentNum) } keyText := fmt.Sprint(key) vRef := e.toPointer(v) // during the second encoding, an anchor is assigned if it is found to be used by an alias. if aliasName, exists := e.getSmartAlias(vRef); exists { anchorName := aliasName anchorNode := ast.Anchor(token.New("&", "&", e.pos(column))) anchorNode.Name = ast.String(token.New(anchorName, anchorName, e.pos(column))) anchorNode.Value = encoded encoded = anchorNode } node.Values = append(node.Values, ast.MappingValue( nil, e.encodeString(keyText, column), encoded, )) e.setSmartAnchor(vRef, keyText) } return node, nil } // IsZeroer is used to check whether an object is zero to determine // whether it should be omitted when marshaling with the omitempty flag. // One notable implementation is time.Time. type IsZeroer interface { IsZero() bool } func (e *Encoder) isOmittedByOmitZero(v reflect.Value) bool { kind := v.Kind() if z, ok := v.Interface().(IsZeroer); ok { if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() { return true } return z.IsZero() } switch kind { case reflect.String: return len(v.String()) == 0 case reflect.Interface, reflect.Ptr, reflect.Slice, reflect.Map: return v.IsNil() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Bool: return !v.Bool() case reflect.Struct: vt := v.Type() for i := v.NumField() - 1; i >= 0; i-- { if vt.Field(i).PkgPath != "" { continue // private field } if !e.isOmittedByOmitZero(v.Field(i)) { return false } } return true } return false } func (e *Encoder) isOmittedByOmitEmptyOption(v reflect.Value) bool { switch v.Kind() { case reflect.String: return len(v.String()) == 0 case reflect.Interface, reflect.Ptr: return v.IsNil() case reflect.Slice, reflect.Map: return v.Len() == 0 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Bool: return !v.Bool() } return false } // The current implementation of the omitempty tag combines the functionality of encoding/json's omitempty and omitzero tags. // This stems from a historical decision to respect the implementation of gopkg.in/yaml.v2, but it has caused confusion, // so we are working to integrate it into the functionality of encoding/json. (However, this will take some time.) // In the current implementation, in addition to the exclusion conditions of omitempty, // if a type implements IsZero, that implementation will be used. // Furthermore, for non-pointer structs, if all fields are eligible for exclusion, // the struct itself will also be excluded. These behaviors are originally the functionality of omitzero. func (e *Encoder) isOmittedByOmitEmptyTag(v reflect.Value) bool { kind := v.Kind() if z, ok := v.Interface().(IsZeroer); ok { if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() { return true } return z.IsZero() } switch kind { case reflect.String: return len(v.String()) == 0 case reflect.Interface, reflect.Ptr: return v.IsNil() case reflect.Slice, reflect.Map: return v.Len() == 0 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Bool: return !v.Bool() case reflect.Struct: vt := v.Type() for i := v.NumField() - 1; i >= 0; i-- { if vt.Field(i).PkgPath != "" { continue // private field } if !e.isOmittedByOmitEmptyTag(v.Field(i)) { return false } } return true } return false } func (e *Encoder) encodeTime(v time.Time, column int) *ast.StringNode { value := v.Format(time.RFC3339Nano) if e.isJSONStyle { value = strconv.Quote(value) } return ast.String(token.New(value, value, e.pos(column))) } func (e *Encoder) encodeDuration(v time.Duration, column int) *ast.StringNode { value := v.String() if e.isJSONStyle { value = strconv.Quote(value) } return ast.String(token.New(value, value, e.pos(column))) } func (e *Encoder) encodeAnchor(anchorName string, value ast.Node, fieldValue reflect.Value, column int) (*ast.AnchorNode, error) { anchorNode := ast.Anchor(token.New("&", "&", e.pos(column))) anchorNode.Name = ast.String(token.New(anchorName, anchorName, e.pos(column))) anchorNode.Value = value if e.anchorCallback != nil { if err := e.anchorCallback(anchorNode, fieldValue.Interface()); err != nil { return nil, err } if snode, ok := anchorNode.Name.(*ast.StringNode); ok { anchorName = snode.Value } } if fieldValue.Kind() == reflect.Ptr { e.setAnchor(fieldValue.Pointer(), anchorName) } return anchorNode, nil } func (e *Encoder) encodeStruct(ctx context.Context, value reflect.Value, column int) (ast.Node, error) { node := ast.Mapping(token.New("", "", e.pos(column)), e.isFlowStyle) structType := value.Type() fieldMap, err := structFieldMap(structType) if err != nil { return nil, err } hasInlineAnchorField := false var inlineAnchorValue reflect.Value for i := 0; i < value.NumField(); i++ { field := structType.Field(i) if isIgnoredStructField(field) { continue } fieldValue := value.FieldByName(field.Name) sf := fieldMap[field.Name] if (e.omitZero || sf.IsOmitZero) && e.isOmittedByOmitZero(fieldValue) { // omit encoding by omitzero tag or OmitZero option. continue } if e.omitEmpty && e.isOmittedByOmitEmptyOption(fieldValue) { // omit encoding by OmitEmpty option. continue } if sf.IsOmitEmpty && e.isOmittedByOmitEmptyTag(fieldValue) { // omit encoding by omitempty tag. continue } ve := e if !e.isFlowStyle && sf.IsFlow { ve = &Encoder{} *ve = *e ve.isFlowStyle = true } encoded, err := ve.encodeValue(ctx, fieldValue, column) if err != nil { return nil, err } if e.isMapNode(encoded) { encoded.AddColumn(e.indentNum) } var key ast.MapKeyNode = e.encodeString(sf.RenderName, column) switch { case encoded.Type() == ast.AliasType: if aliasName := sf.AliasName; aliasName != "" { alias, ok := encoded.(*ast.AliasNode) if !ok { return nil, errors.ErrUnexpectedNodeType(encoded.Type(), ast.AliasType, encoded.GetToken()) } got := alias.Value.String() if aliasName != got { return nil, fmt.Errorf("expected alias name is %q but got %q", aliasName, got) } } if sf.IsInline { // if both used alias and inline, output `<<: *alias` key = ast.MergeKey(token.New("<<", "<<", e.pos(column))) } case sf.AnchorName != "": anchorNode, err := e.encodeAnchor(sf.AnchorName, encoded, fieldValue, column) if err != nil { return nil, err } encoded = anchorNode case sf.IsInline: isAutoAnchor := sf.IsAutoAnchor if !hasInlineAnchorField { hasInlineAnchorField = isAutoAnchor } if isAutoAnchor { inlineAnchorValue = fieldValue } mapNode, ok := encoded.(ast.MapNode) if !ok { // if an inline field is null, skip encoding it if _, ok := encoded.(*ast.NullNode); ok { continue } return nil, errors.New("inline value is must be map or struct type") } mapIter := mapNode.MapRange() for mapIter.Next() { mapKey := mapIter.Key() mapValue := mapIter.Value() keyName := mapKey.GetToken().Value if fieldMap.isIncludedRenderName(keyName) { // if declared the same key name, skip encoding this field continue } mapKey.AddColumn(-e.indentNum) mapValue.AddColumn(-e.indentNum) node.Values = append(node.Values, ast.MappingValue(nil, mapKey, mapValue)) } continue case sf.IsAutoAnchor: anchorNode, err := e.encodeAnchor(sf.RenderName, encoded, fieldValue, column) if err != nil { return nil, err } encoded = anchorNode } node.Values = append(node.Values, ast.MappingValue(nil, key, encoded)) } if hasInlineAnchorField { node.AddColumn(e.indentNum) anchorName := "anchor" anchorNode := ast.Anchor(token.New("&", "&", e.pos(column))) anchorNode.Name = ast.String(token.New(anchorName, anchorName, e.pos(column))) anchorNode.Value = node if e.anchorCallback != nil { if err := e.anchorCallback(anchorNode, value.Addr().Interface()); err != nil { return nil, err } if snode, ok := anchorNode.Name.(*ast.StringNode); ok { anchorName = snode.Value } } if inlineAnchorValue.Kind() == reflect.Ptr { e.setAnchor(inlineAnchorValue.Pointer(), anchorName) } return anchorNode, nil } return node, nil } func (e *Encoder) toPointer(v reflect.Value) uintptr { if e.isInvalidValue(v) { return 0 } switch v.Type().Kind() { case reflect.Ptr: return v.Pointer() case reflect.Interface: return e.toPointer(v.Elem()) case reflect.Slice: return v.Pointer() case reflect.Map: return v.Pointer() } return 0 } func (e *Encoder) clearSmartAnchorRef() { if !e.enableSmartAnchor { return } e.anchorRefToName = make(map[uintptr]string) e.anchorNameMap = make(map[string]struct{}) } func (e *Encoder) setSmartAnchor(ptr uintptr, name string) { if !e.enableSmartAnchor { return } e.setAnchor(ptr, e.generateAnchorName(name)) } func (e *Encoder) setAnchor(ptr uintptr, name string) { if ptr == 0 { return } if name == "" { return } e.anchorRefToName[ptr] = name e.anchorNameMap[name] = struct{}{} } func (e *Encoder) generateAnchorName(base string) string { if _, exists := e.anchorNameMap[base]; !exists { return base } for i := 1; i < 100; i++ { name := base + strconv.Itoa(i) if _, exists := e.anchorNameMap[name]; exists { continue } return name } return "" } func (e *Encoder) getAnchor(ref uintptr) (string, bool) { anchorName, exists := e.anchorRefToName[ref] return anchorName, exists } func (e *Encoder) setSmartAlias(name string, ref uintptr) { if !e.enableSmartAnchor { return } e.aliasRefToName[ref] = name } func (e *Encoder) getSmartAlias(ref uintptr) (string, bool) { if !e.enableSmartAnchor { return "", false } aliasName, exists := e.aliasRefToName[ref] return aliasName, exists } goccy-go-yaml-52dacb8/encode_test.go000066400000000000000000001152731501576637100175220ustar00rootroot00000000000000package yaml_test import ( "bytes" "context" "errors" "fmt" "math" "net/netip" "reflect" "strconv" "strings" "testing" "time" "unsafe" "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/parser" ) var zero = 0 var emptyStr = "" type TestTextMarshaler string func (t TestTextMarshaler) MarshalText() ([]byte, error) { return []byte(t), nil } type TestTextUnmarshalerContainer struct { V TestTextMarshaler } func TestEncoder(t *testing.T) { tests := []struct { source string value interface{} options []yaml.EncodeOption }{ { "null\n", (*struct{})(nil), nil, }, { "v: hi\n", map[string]string{"v": "hi"}, nil, }, { "v: \"true\"\n", map[string]string{"v": "true"}, nil, }, { "v: \"false\"\n", map[string]string{"v": "false"}, nil, }, { "v: true\n", map[string]interface{}{"v": true}, nil, }, { "v: false\n", map[string]bool{"v": false}, nil, }, { "v: 10\n", map[string]int{"v": 10}, nil, }, { "v: -10\n", map[string]int{"v": -10}, nil, }, { "v: 4294967296\n", map[string]int64{"v": int64(4294967296)}, nil, }, { "v: 0.1\n", map[string]interface{}{"v": 0.1}, nil, }, { "v: 0.99\n", map[string]float32{"v": 0.99}, nil, }, { "v: 1e-06\n", map[string]float32{"v": 1e-06}, nil, }, { "v: 1e-06\n", map[string]float64{"v": 0.000001}, nil, }, { "v: 0.123456789\n", map[string]float64{"v": 0.123456789}, nil, }, { "v: -0.1\n", map[string]float64{"v": -0.1}, nil, }, { "v: 1.0\n", map[string]float64{"v": 1.0}, nil, }, { "v: 1e+06\n", map[string]float64{"v": 1000000}, nil, }, { "v: 1e-06\n", map[string]float64{"v": 0.000001}, nil, }, { "v: 1e-06\n", map[string]float64{"v": 1e-06}, nil, }, { "v: .inf\n", map[string]interface{}{"v": math.Inf(0)}, nil, }, { "v: -.inf\n", map[string]interface{}{"v": math.Inf(-1)}, nil, }, { "v: .nan\n", map[string]interface{}{"v": math.NaN()}, nil, }, { "v: null\n", map[string]interface{}{"v": nil}, nil, }, { "v: \"\"\n", map[string]string{"v": ""}, nil, }, { "v:\n- A\n- B\n", map[string][]string{"v": {"A", "B"}}, nil, }, { "v:\n - A\n - B\n", map[string][]string{"v": {"A", "B"}}, []yaml.EncodeOption{ yaml.IndentSequence(true), }, }, { "v:\n- A\n- B\n", map[string][2]string{"v": {"A", "B"}}, nil, }, { "v:\n - A\n - B\n", map[string][2]string{"v": {"A", "B"}}, []yaml.EncodeOption{ yaml.IndentSequence(true), }, }, { "a: \"-\"\n", map[string]string{"a": "-"}, nil, }, { "123\n", 123, nil, }, { "hello: world\n", map[string]string{"hello": "world"}, nil, }, { "hello: |\n hello\n world\n", map[string]string{"hello": "hello\nworld\n"}, nil, }, { "hello: |-\n hello\n world\n", map[string]string{"hello": "hello\nworld"}, nil, }, { "hello: |+\n hello\n world\n\n", map[string]string{"hello": "hello\nworld\n\n"}, nil, }, { "hello:\n hello: |\n hello\n world\n", map[string]map[string]string{"hello": {"hello": "hello\nworld\n"}}, nil, }, { "hello: |\r hello\r world\n", map[string]string{"hello": "hello\rworld\r"}, nil, }, { "hello: |\r\n hello\r\n world\n", map[string]string{"hello": "hello\r\nworld\r\n"}, nil, }, { "v: |-\n username: hello\n password: hello123\n", map[string]interface{}{"v": "username: hello\npassword: hello123"}, []yaml.EncodeOption{ yaml.UseLiteralStyleIfMultiline(true), }, }, { "v: |-\n # comment\n username: hello\n password: hello123\n", map[string]interface{}{"v": "# comment\nusername: hello\npassword: hello123"}, []yaml.EncodeOption{ yaml.UseLiteralStyleIfMultiline(true), }, }, { "v: \"# comment\\nusername: hello\\npassword: hello123\"\n", map[string]interface{}{"v": "# comment\nusername: hello\npassword: hello123"}, []yaml.EncodeOption{ yaml.UseLiteralStyleIfMultiline(false), }, }, { "v:\n- A\n- 1\n- B:\n - 2\n - 3\n", map[string]interface{}{ "v": []interface{}{ "A", 1, map[string][]int{ "B": {2, 3}, }, }, }, nil, }, { "v:\n - A\n - 1\n - B:\n - 2\n - 3\n - 2\n", map[string]interface{}{ "v": []interface{}{ "A", 1, map[string][]int{ "B": {2, 3}, }, 2, }, }, []yaml.EncodeOption{ yaml.IndentSequence(true), }, }, { "a:\n b: c\n", map[string]interface{}{ "a": map[string]string{ "b": "c", }, }, nil, }, { "t2: \"2018-01-09T10:40:47Z\"\nt4: \"2098-01-09T10:40:47Z\"\n", map[string]string{ "t2": "2018-01-09T10:40:47Z", "t4": "2098-01-09T10:40:47Z", }, nil, }, { "a:\n b: c\n d: e\n", map[string]interface{}{ "a": map[string]string{ "b": "c", "d": "e", }, }, nil, }, { "a: 3s\n", map[string]string{ "a": "3s", }, nil, }, { "a: \n", map[string]string{"a": ""}, nil, }, { "a: \"1:1\"\n", map[string]string{"a": "1:1"}, nil, }, { "a: 1.2.3.4\n", map[string]string{"a": "1.2.3.4"}, nil, }, { "a: \"b: c\"\n", map[string]string{"a": "b: c"}, nil, }, { "a: \"Hello #comment\"\n", map[string]string{"a": "Hello #comment"}, nil, }, { "a: \" b\"\n", map[string]string{"a": " b"}, nil, }, { "a: \"b \"\n", map[string]string{"a": "b "}, nil, }, { "a: \" b \"\n", map[string]string{"a": " b "}, nil, }, { "a: \"`b` c\"\n", map[string]string{"a": "`b` c"}, nil, }, { "a: 100.5\n", map[string]interface{}{ "a": 100.5, }, nil, }, { "a: \"\\\\0\"\n", map[string]string{"a": "\\0"}, nil, }, { "a: 1\nb: 2\nc: 3\nd: 4\nsub:\n e: 5\n", map[string]interface{}{ "a": 1, "b": 2, "c": 3, "d": 4, "sub": map[string]int{ "e": 5, }, }, nil, }, { "a: 1\nb: []\n", struct { A int B []string }{ 1, ([]string)(nil), }, nil, }, { "a: 1\nb: []\n", struct { A int B []string }{ 1, []string{}, }, nil, }, { "a: {}\n", struct { A map[string]interface{} }{ map[string]interface{}{}, }, nil, }, { "a: b\nc: d\n", struct { A string C string `yaml:"c"` }{ "b", "d", }, nil, }, { "a: 1\n", struct { A int B int `yaml:"-"` }{ 1, 0, }, nil, }, { "a: \"\"\n", struct { A string }{ "", }, nil, }, { "a: null\n", struct { A *string }{ nil, }, nil, }, { "a: \"\"\n", struct { A *string }{ &emptyStr, }, nil, }, { "a: null\n", struct { A *int }{ nil, }, nil, }, { "a: 0\n", struct { A *int }{ &zero, }, nil, }, // Omitempty flag. { "a: 1\n", struct { A int `yaml:"a,omitempty"` B int `yaml:"b,omitempty"` }{1, 0}, nil, }, { "{}\n", struct { A int `yaml:"a,omitempty"` B int `yaml:"b,omitempty"` }{0, 0}, nil, }, { "a:\n \"y\": \"\"\n", struct { A *struct { X string `yaml:"x,omitempty"` Y string } }{&struct { X string `yaml:"x,omitempty"` Y string }{}}, nil, }, { "a: {}\n", struct { A *struct { X string `yaml:"x,omitempty"` Y string `yaml:"y,omitempty"` } }{&struct { X string `yaml:"x,omitempty"` Y string `yaml:"y,omitempty"` }{}}, nil, }, { "a: {x: 1}\n", struct { A *struct{ X, y int } `yaml:"a,omitempty,flow"` }{&struct{ X, y int }{1, 2}}, nil, }, { "{}\n", struct { A *struct{ X, y int } `yaml:"a,omitempty,flow"` }{nil}, nil, }, { "a: {x: 0}\n", struct { A *struct{ X, y int } `yaml:"a,omitempty,flow"` }{&struct{ X, y int }{}}, nil, }, { "a: {x: 1}\n", struct { A struct{ X, y int } `yaml:"a,omitempty,flow"` }{struct{ X, y int }{1, 2}}, nil, }, { "{}\n", struct { A struct{ X, y int } `yaml:"a,omitempty,flow"` }{struct{ X, y int }{0, 1}}, nil, }, { "a: 1.0\n", struct { A float64 `yaml:"a,omitempty"` B float64 `yaml:"b,omitempty"` }{1, 0}, nil, }, { "a: 1\n", struct { A int B []string `yaml:"b,omitempty"` }{ 1, []string{}, }, nil, }, // Highlighting differences of go-yaml omitempty vs std encoding/json // omitempty. Encoding/json will emit the following fields: https://go.dev/play/p/VvNpdM0GD4d { "{}\n", struct { // This type has a custom IsZero method. A netip.Addr `yaml:"a,omitempty"` B struct{ X, y int } `yaml:"b,omitempty"` }{}, nil, }, // omitzero flag. { "a: 1\n", struct { A int `yaml:"a,omitzero"` B int `yaml:"b,omitzero"` }{1, 0}, nil, }, { "{}\n", struct { A int `yaml:"a,omitzero"` B int `yaml:"b,omitzero"` }{0, 0}, nil, }, { "a:\n \"y\": \"\"\n", struct { A *struct { X string `yaml:"x,omitzero"` Y string } }{&struct { X string `yaml:"x,omitzero"` Y string }{}}, nil, }, { "a: {}\n", struct { A *struct { X string `yaml:"x,omitzero"` Y string `yaml:"y,omitzero"` } }{&struct { X string `yaml:"x,omitzero"` Y string `yaml:"y,omitzero"` }{}}, nil, }, { "a: {x: 1}\n", struct { A *struct{ X, y int } `yaml:"a,omitzero,flow"` }{&struct{ X, y int }{1, 2}}, nil, }, { "{}\n", struct { A *struct{ X, y int } `yaml:"a,omitzero,flow"` }{nil}, nil, }, { "a: {x: 0}\n", struct { A *struct{ X, y int } `yaml:"a,omitzero,flow"` }{&struct{ X, y int }{}}, nil, }, { "a: {x: 1}\n", struct { A struct{ X, y int } `yaml:"a,omitzero,flow"` }{struct{ X, y int }{1, 2}}, nil, }, { "{}\n", struct { A struct{ X, y int } `yaml:"a,omitzero,flow"` }{struct{ X, y int }{0, 1}}, nil, }, { "a: 1.0\n", struct { A float64 `yaml:"a,omitzero"` B float64 `yaml:"b,omitzero"` }{1, 0}, nil, }, { "a: 1\nb: []\n", struct { A int B []string `yaml:"b,omitzero"` }{ 1, []string{}, }, nil, }, { "{}\n", struct { A netip.Addr `yaml:"a,omitzero"` B struct{ X, y int } `yaml:"b,omitzero"` }{}, nil, }, // OmitEmpty global option. { "a: 1\n", struct { A int B int `yaml:"b,omitempty"` }{1, 0}, []yaml.EncodeOption{ yaml.OmitEmpty(), }, }, { "{}\n", struct { A int B int `yaml:"b,omitempty"` }{0, 0}, []yaml.EncodeOption{ yaml.OmitEmpty(), }, }, { "a: \"\"\nb: {}\n", struct { A netip.Addr `yaml:"a"` B struct{ X, y int } `yaml:"b"` }{}, []yaml.EncodeOption{ yaml.OmitEmpty(), }, }, // OmitZero global option. { "a: 1\n", struct { A int B int }{1, 0}, []yaml.EncodeOption{ yaml.OmitZero(), }, }, { "{}\n", struct { A int B int }{0, 0}, []yaml.EncodeOption{ yaml.OmitZero(), }, }, { "{}\n", struct { A netip.Addr `yaml:"a"` B struct{ X, y int } `yaml:"b"` }{}, []yaml.EncodeOption{ yaml.OmitZero(), }, }, // Flow flag. { "a: [1, 2]\n", struct { A []int `yaml:"a,flow"` }{[]int{1, 2}}, nil, }, { "a: {b: c, d: e}\n", &struct { A map[string]string `yaml:"a,flow"` }{map[string]string{"b": "c", "d": "e"}}, nil, }, { "a: {b: c, d: e}\n", struct { A struct { B, D string } `yaml:"a,flow"` }{struct{ B, D string }{"c", "e"}}, nil, }, // Quoting in flow mode { `a: [b, "c,d", e]` + "\n", struct { A []string `yaml:"a,flow"` }{[]string{"b", "c,d", "e"}}, []yaml.EncodeOption{ yaml.UseSingleQuote(false), }, }, { `a: [b, "c]", d]` + "\n", struct { A []string `yaml:"a,flow"` }{[]string{"b", "c]", "d"}}, []yaml.EncodeOption{ yaml.UseSingleQuote(false), }, }, { `a: [b, "c}", d]` + "\n", struct { A []string `yaml:"a,flow"` }{[]string{"b", "c}", "d"}}, []yaml.EncodeOption{ yaml.UseSingleQuote(false), }, }, { `a: [b, "c\"", d]` + "\n", struct { A []string `yaml:"a,flow"` }{[]string{"b", `c"`, "d"}}, []yaml.EncodeOption{ yaml.UseSingleQuote(false), }, }, { `a: [b, "c'", d]` + "\n", struct { A []string `yaml:"a,flow"` }{[]string{"b", "c'", "d"}}, []yaml.EncodeOption{ yaml.UseSingleQuote(false), }, }, // No quoting in non-flow mode { "a:\n- b\n- c,d\n- e\n", struct { A []string `yaml:"a"` }{[]string{"b", "c,d", "e"}}, nil, }, { `a: [b, "c]", d]` + "\n", struct { A []string `yaml:"a,flow"` }{[]string{"b", "c]", "d"}}, nil, }, { `a: [b, "c}", d]` + "\n", struct { A []string `yaml:"a,flow"` }{[]string{"b", "c}", "d"}}, nil, }, { `a: [b, "c\"", d]` + "\n", struct { A []string `yaml:"a,flow"` }{[]string{"b", `c"`, "d"}}, nil, }, { `a: [b, "c'", d]` + "\n", struct { A []string `yaml:"a,flow"` }{[]string{"b", "c'", "d"}}, nil, }, // Multi bytes { "v: あいうえお\nv2: かきくけこ\n", map[string]string{"v": "あいうえお", "v2": "かきくけこ"}, nil, }, // time value { "v: 0001-01-01T00:00:00Z\n", map[string]time.Time{"v": {}}, nil, }, { "v: 0001-01-01T00:00:00Z\n", map[string]*time.Time{"v": {}}, nil, }, { "v: null\n", map[string]*time.Time{"v": nil}, nil, }, { "v: 30s\n", map[string]time.Duration{"v": 30 * time.Second}, nil, }, { "v: 30s\n", map[string]*time.Duration{"v": ptr(30 * time.Second)}, nil, }, { "v: null\n", map[string]*time.Duration{"v": nil}, nil, }, { "v: test\n", TestTextUnmarshalerContainer{V: "test"}, nil, }, { "v: \"1\"\n", TestTextUnmarshalerContainer{V: "1"}, nil, }, { "v: \"#\"\n", TestTextUnmarshalerContainer{V: "#"}, nil, }, // Quote style { `v: '''a''b'` + "\n", map[string]string{"v": `'a'b`}, []yaml.EncodeOption{ yaml.UseSingleQuote(true), }, }, { `v: "'a'b"` + "\n", map[string]string{"v": `'a'b`}, []yaml.EncodeOption{ yaml.UseSingleQuote(false), }, }, { `a: '\.yaml'` + "\n", map[string]string{"a": `\.yaml`}, []yaml.EncodeOption{ yaml.UseSingleQuote(true), }, }, } for _, test := range tests { t.Run(test.source, func(t *testing.T) { var buf bytes.Buffer enc := yaml.NewEncoder(&buf, test.options...) if err := enc.Encode(test.value); err != nil { t.Fatalf("%+v", err) } if test.source != buf.String() { t.Fatalf("expect = [%s], actual = [%s]", test.source, buf.String()) } }) } } func TestEncodeStructIncludeMap(t *testing.T) { type U struct { M map[string]string } type T struct { A U } bytes, err := yaml.Marshal(T{ A: U{ M: map[string]string{"x": "y"}, }, }) if err != nil { t.Fatalf("%+v", err) } expect := "a:\n m:\n x: \"y\"\n" actual := string(bytes) if actual != expect { t.Fatalf("unexpected output. expect:[%s] actual:[%s]", expect, actual) } } func TestEncodeDefinedTypeKeyMap(t *testing.T) { type K string type U struct { M map[K]string } bytes, err := yaml.Marshal(U{ M: map[K]string{K("x"): "y"}, }) if err != nil { t.Fatalf("%+v", err) } expect := "m:\n x: \"y\"\n" actual := string(bytes) if actual != expect { t.Fatalf("unexpected output. expect:[%s] actual:[%s]", expect, actual) } } func TestEncodeWithAnchorAndAlias(t *testing.T) { var buf bytes.Buffer enc := yaml.NewEncoder(&buf) type T struct { A int B string } var v struct { A *T `yaml:"a,anchor=c"` B *T `yaml:"b,alias=c"` } v.A = &T{A: 1, B: "hello"} v.B = v.A if err := enc.Encode(v); err != nil { t.Fatalf("%+v", err) } expect := "a: &c\n a: 1\n b: hello\nb: *c\n" if expect != buf.String() { t.Fatalf("expect = [%s], actual = [%s]", expect, buf.String()) } } func TestEncodeWithAutoAlias(t *testing.T) { var buf bytes.Buffer enc := yaml.NewEncoder(&buf) type T struct { I int S string } var v struct { A *T `yaml:"a,anchor=a"` B *T `yaml:"b,anchor=b"` C *T `yaml:"c"` D *T `yaml:"d"` } v.A = &T{I: 1, S: "hello"} v.B = &T{I: 2, S: "world"} v.C = v.A v.D = v.B if err := enc.Encode(v); err != nil { t.Fatalf("%+v", err) } expect := `a: &a i: 1 s: hello b: &b i: 2 s: world c: *a d: *b ` if expect != buf.String() { t.Fatalf("expect = [%s], actual = [%s]", expect, buf.String()) } } func TestEncodeWithImplicitAnchorAndAlias(t *testing.T) { var buf bytes.Buffer enc := yaml.NewEncoder(&buf) type T struct { I int S string } var v struct { A *T `yaml:"a,anchor"` B *T `yaml:"b,anchor"` C *T `yaml:"c"` D *T `yaml:"d"` } v.A = &T{I: 1, S: "hello"} v.B = &T{I: 2, S: "world"} v.C = v.A v.D = v.B if err := enc.Encode(v); err != nil { t.Fatalf("%+v", err) } expect := `a: &a i: 1 s: hello b: &b i: 2 s: world c: *a d: *b ` if expect != buf.String() { t.Fatalf("expect = [%s], actual = [%s]", expect, buf.String()) } } func TestEncodeWithMerge(t *testing.T) { type Person struct { *Person `yaml:",omitempty,inline"` Name string `yaml:",omitempty"` Age int `yaml:",omitempty"` } defaultPerson := &Person{ Name: "John Smith", Age: 20, } people := []*Person{ { Person: defaultPerson, Name: "Ken", Age: 10, }, { Person: defaultPerson, }, } var doc struct { Default *Person `yaml:"default,anchor"` People []*Person `yaml:"people"` } doc.Default = defaultPerson doc.People = people var buf bytes.Buffer enc := yaml.NewEncoder(&buf) if err := enc.Encode(doc); err != nil { t.Fatalf("%+v", err) } expect := `default: &default name: John Smith age: 20 people: - <<: *default name: Ken age: 10 - <<: *default ` if expect != buf.String() { t.Fatalf("expect = [%s], actual = [%s]", expect, buf.String()) } } func TestEncodeWithNestedYAML(t *testing.T) { // Represents objects containing stringified YAML, and special chars tests := []struct { value interface{} // If true, expects a different result between when using forced literal style or not expectDifferent bool }{ { value: map[string]interface{}{"v": "# comment\nname: hello\npassword: hello123\nspecial: \":ghost:\"\ntext: |\n nested multiline!"}, expectDifferent: true, }, { value: map[string]interface{}{"v": "# comment\nusername: hello\npassword: hello123"}, expectDifferent: true, }, { value: map[string]interface{}{"v": "# comment\n"}, expectDifferent: true, }, } for _, test := range tests { yamlBytesForced, err := yaml.MarshalWithOptions(test.value, yaml.UseLiteralStyleIfMultiline(true)) if err != nil { t.Fatalf("%+v", err) } // Convert it back for proper equality testing var unmarshaled interface{} if err := yaml.Unmarshal(yamlBytesForced, &unmarshaled); err != nil { t.Fatalf("%+v", err) } if !reflect.DeepEqual(test.value, unmarshaled) { t.Fatalf("expected %v(%T). but actual %v(%T)", test.value, test.value, unmarshaled, unmarshaled) } if test.expectDifferent { yamlBytesNotForced, err := yaml.MarshalWithOptions(test.value) if err != nil { t.Fatalf("%+v", err) } if string(yamlBytesForced) == string(yamlBytesNotForced) { t.Fatalf("expected different strings when force literal style is not enabled. forced: %s, not forced: %s", string(yamlBytesForced), string(yamlBytesNotForced)) } } } } func TestEncoder_Inline(t *testing.T) { type base struct { A int B string } var buf bytes.Buffer enc := yaml.NewEncoder(&buf) if err := enc.Encode(struct { *base `yaml:",inline"` C bool }{ base: &base{ A: 1, B: "hello", }, C: true, }); err != nil { t.Fatalf("%+v", err) } expect := ` a: 1 b: hello c: true ` actual := "\n" + buf.String() if expect != actual { t.Fatalf("inline marshal error: expect=[%s] actual=[%s]", expect, actual) } } func TestEncoder_InlineAndConflictKey(t *testing.T) { type base struct { A int B string } var buf bytes.Buffer enc := yaml.NewEncoder(&buf) if err := enc.Encode(struct { *base `yaml:",inline"` A int // conflict C bool }{ base: &base{ A: 1, B: "hello", }, A: 0, // default value C: true, }); err != nil { t.Fatalf("%+v", err) } expect := ` b: hello a: 0 c: true ` actual := "\n" + buf.String() if expect != actual { t.Fatalf("inline marshal error: expect=[%s] actual=[%s]", expect, actual) } } func TestEncoder_InlineNil(t *testing.T) { type base struct { A int B string } var buf bytes.Buffer enc := yaml.NewEncoder(&buf) if err := enc.Encode(struct { *base `yaml:",inline"` C bool }{ C: true, }); err != nil { t.Fatalf("%+v", err) } expect := ` c: true ` actual := "\n" + buf.String() if expect != actual { t.Fatalf("inline marshal error: expect=[%s] actual=[%s]", expect, actual) } } func TestEncoder_Flow(t *testing.T) { var buf bytes.Buffer enc := yaml.NewEncoder(&buf, yaml.Flow(true)) var v struct { A int B string C struct { D int E string } F []int } v.A = 1 v.B = "hello" v.C.D = 3 v.C.E = "world" v.F = []int{1, 2} if err := enc.Encode(v); err != nil { t.Fatalf("%+v", err) } expect := ` {a: 1, b: hello, c: {d: 3, e: world}, f: [1, 2]} ` actual := "\n" + buf.String() if expect != actual { t.Fatalf("flow style marshal error: expect=[%s] actual=[%s]", expect, actual) } } func TestEncoder_FlowRecursive(t *testing.T) { var v struct { M map[string][]int `yaml:",flow"` } v.M = map[string][]int{ "test": {1, 2, 3}, } var buf bytes.Buffer if err := yaml.NewEncoder(&buf).Encode(v); err != nil { t.Fatalf("%+v", err) } expect := ` m: {test: [1, 2, 3]} ` actual := "\n" + buf.String() if expect != actual { t.Fatalf("flow style marshal error: expect=[%s] actual=[%s]", expect, actual) } } func TestEncoder_JSON(t *testing.T) { var buf bytes.Buffer enc := yaml.NewEncoder(&buf, yaml.JSON()) type st struct { I int8 S string F float32 } if err := enc.Encode(struct { I int U uint S string F float64 Struct *st Slice []int Map map[string]interface{} Time time.Time Duration time.Duration }{ I: -10, U: 10, S: "hello", F: 3.14, Struct: &st{ I: 2, S: "world", F: 1.23, }, Slice: []int{1, 2, 3, 4, 5}, Map: map[string]interface{}{ "a": 1, "b": 1.23, "c": "json", }, Time: time.Time{}, Duration: 5 * time.Minute, }); err != nil { t.Fatalf("%+v", err) } expect := ` {"i": -10, "u": 10, "s": "hello", "f": 3.14, "struct": {"i": 2, "s": "world", "f": 1.23}, "slice": [1, 2, 3, 4, 5], "map": {"a": 1, "b": 1.23, "c": "json"}, "time": "0001-01-01T00:00:00Z", "duration": "5m0s"} ` actual := "\n" + buf.String() if expect != actual { t.Fatalf("JSON style marshal error: expect=[%s] actual=[%s]", expect, actual) } } func TestEncoder_MarshalAnchor(t *testing.T) { type Host struct { Hostname string Username string Password string } type HostDecl struct { Host *Host `yaml:",anchor"` } type Queue struct { Name string `yaml:","` *Host } var doc struct { Hosts []*HostDecl `yaml:"hosts"` Queues []*Queue `yaml:"queues"` } host1 := &Host{ Hostname: "host1.example.com", Username: "userA", Password: "pass1", } host2 := &Host{ Hostname: "host2.example.com", Username: "userB", Password: "pass2", } doc.Hosts = []*HostDecl{ { Host: host1, }, { Host: host2, }, } doc.Queues = []*Queue{ { Name: "queue", Host: host1, }, { Name: "queue2", Host: host2, }, } hostIdx := 1 opt := yaml.MarshalAnchor(func(anchor *ast.AnchorNode, value interface{}) error { if _, ok := value.(*Host); ok { nameNode, _ := anchor.Name.(*ast.StringNode) nameNode.Value = fmt.Sprintf("host%d", hostIdx) hostIdx++ } return nil }) var buf bytes.Buffer if err := yaml.NewEncoder(&buf, opt).Encode(doc); err != nil { t.Fatalf("%+v", err) } expect := ` hosts: - host: &host1 hostname: host1.example.com username: userA password: pass1 - host: &host2 hostname: host2.example.com username: userB password: pass2 queues: - name: queue host: *host1 - name: queue2 host: *host2 ` if "\n"+buf.String() != expect { t.Fatalf("unexpected output. %s", buf.String()) } } type useJSONMarshalerTest struct{} func (t useJSONMarshalerTest) MarshalJSON() ([]byte, error) { return []byte(`{"a":[1, 2, 3]}`), nil } func TestEncoder_UseJSONMarshaler(t *testing.T) { got, err := yaml.MarshalWithOptions(useJSONMarshalerTest{}, yaml.UseJSONMarshaler()) if err != nil { t.Fatal(err) } expected := ` a: - 1 - 2 - 3 ` if expected != "\n"+string(got) { t.Fatalf("failed to use json marshaler. expected [%q] but got [%q]", expected, string(got)) } } func TestEncoder_CustomMarshaler(t *testing.T) { t.Run("override struct type", func(t *testing.T) { type T struct { Foo string `yaml:"foo"` } b, err := yaml.MarshalWithOptions(&T{Foo: "bar"}, yaml.CustomMarshaler[T](func(v T) ([]byte, error) { return []byte(`"override"`), nil })) if err != nil { t.Fatal(err) } if !bytes.Equal(b, []byte("\"override\"\n")) { t.Fatalf("failed to switch to custom marshaler. got: %q", b) } }) t.Run("override bytes type", func(t *testing.T) { type T struct { Foo []byte `yaml:"foo"` } b, err := yaml.MarshalWithOptions(&T{Foo: []byte("bar")}, yaml.CustomMarshaler[[]byte](func(v []byte) ([]byte, error) { if !bytes.Equal(v, []byte("bar")) { t.Fatalf("failed to get src buffer: %q", v) } return []byte(`override`), nil })) if err != nil { t.Fatal(err) } if !bytes.Equal(b, []byte("foo: override\n")) { t.Fatalf("failed to switch to custom marshaler. got: %q", b) } }) t.Run("override bytes type with context", func(t *testing.T) { type T struct { Foo []byte `yaml:"foo"` } ctx := context.WithValue(context.Background(), "plop", uint(42)) b, err := yaml.MarshalContext(ctx, &T{Foo: []byte("bar")}, yaml.CustomMarshalerContext[[]byte](func(ctx context.Context, v []byte) ([]byte, error) { if !bytes.Equal(v, []byte("bar")) { t.Fatalf("failed to get src buffer: %q", v) } if ctx.Value("plop") != uint(42) { t.Fatalf("context value is not correct") } return []byte(`override`), nil })) if err != nil { t.Fatal(err) } if !bytes.Equal(b, []byte("foo: override\n")) { t.Fatalf("failed to switch to custom marshaler. got: %q", b) } }) } func TestEncoder_AutoInt(t *testing.T) { for _, test := range []struct { desc string input any expected string }{ { desc: "int-convertible float64", input: map[string]float64{ "key": 1.0, }, expected: "key: 1\n", }, { desc: "non int-convertible float64", input: map[string]float64{ "key": 1.1, }, expected: "key: 1.1\n", }, { desc: "int-convertible float32", input: map[string]float32{ "key": 1.0, }, expected: "key: 1\n", }, { desc: "non int-convertible float32", input: map[string]float32{ "key": 1.1, }, expected: "key: 1.1\n", }, } { t.Run(test.desc, func(t *testing.T) { var buf bytes.Buffer enc := yaml.NewEncoder(&buf, yaml.AutoInt()) if err := enc.Encode(test.input); err != nil { t.Fatalf("failed to encode: %s", err) } if actual := buf.String(); actual != test.expected { t.Errorf("expect:\n%s\nactual\n%s\n", test.expected, actual) } }) } } func TestEncoder_MultipleDocuments(t *testing.T) { var buf bytes.Buffer enc := yaml.NewEncoder(&buf) if err := enc.Encode(1); err != nil { t.Fatalf("failed to encode: %s", err) } if err := enc.Encode(2); err != nil { t.Fatalf("failed to encode: %s", err) } if actual, expect := buf.String(), "1\n---\n2\n"; actual != expect { t.Errorf("expect:\n%s\nactual\n%s\n", expect, actual) } } func TestEncoder_UnmarshallableTypes(t *testing.T) { for _, test := range []struct { desc string input any expectedErr string }{ { desc: "channel", input: make(chan int), expectedErr: "unknown value type chan int", }, { desc: "function", input: func() {}, expectedErr: "unknown value type func()", }, { desc: "complex number", input: complex(10, 11), expectedErr: "unknown value type complex128", }, { desc: "unsafe pointer", input: unsafe.Pointer(&struct{}{}), expectedErr: "unknown value type unsafe.Pointer", }, { desc: "uintptr", input: uintptr(0x1234), expectedErr: "unknown value type uintptr", }, { desc: "map with channel", input: map[string]any{"key": make(chan string)}, expectedErr: "unknown value type chan string", }, { desc: "nested map with func", input: map[string]any{ "a": map[string]any{ "b": func(_ string) {}, }, }, expectedErr: "unknown value type func(string)", }, { desc: "slice with channel", input: []any{make(chan bool)}, expectedErr: "unknown value type chan bool", }, { desc: "nested slice with complex number", input: []any{[]any{complex(10, 11)}}, expectedErr: "unknown value type complex128", }, { desc: "struct with unsafe pointer", input: struct { Field unsafe.Pointer `yaml:"field"` }{}, expectedErr: "unknown value type unsafe.Pointer", }, } { t.Run(test.desc, func(t *testing.T) { var buf bytes.Buffer err := yaml.NewEncoder(&buf).Encode(test.input) if err == nil { t.Errorf("expect error:\n%s\nbut got none\n", test.expectedErr) } else if err.Error() != test.expectedErr { t.Errorf("expect error:\n%s\nactual\n%s\n", test.expectedErr, err) } }) } } func ExampleMarshal_node() { type T struct { Text ast.Node `yaml:"text"` } stringNode, err := yaml.ValueToNode("node example") if err != nil { panic(err) } bytes, err := yaml.Marshal(T{Text: stringNode}) if err != nil { panic(err) } fmt.Println(string(bytes)) // OUTPUT: // text: node example } func ExampleMarshal_explicitAnchorAlias() { type T struct { A int B string } var v struct { C *T `yaml:"c,anchor=x"` D *T `yaml:"d,alias=x"` } v.C = &T{A: 1, B: "hello"} v.D = v.C bytes, err := yaml.Marshal(v) if err != nil { panic(err) } fmt.Println(string(bytes)) // OUTPUT: // c: &x // a: 1 // b: hello // d: *x } func ExampleMarshal_implicitAnchorAlias() { type T struct { I int S string } var v struct { A *T `yaml:"a,anchor"` B *T `yaml:"b,anchor"` C *T `yaml:"c"` D *T `yaml:"d"` } v.A = &T{I: 1, S: "hello"} v.B = &T{I: 2, S: "world"} v.C = v.A // C has same pointer address to A v.D = v.B // D has same pointer address to B bytes, err := yaml.Marshal(v) if err != nil { panic(err) } fmt.Println(string(bytes)) // OUTPUT: // a: &a // i: 1 // s: hello // b: &b // i: 2 // s: world // c: *a // d: *b } type tMarshal []string func (t *tMarshal) MarshalYAML() ([]byte, error) { var buf bytes.Buffer buf.WriteString("tags:\n") for i, v := range *t { if i == 0 { fmt.Fprintf(&buf, "- %s\n", v) } else { fmt.Fprintf(&buf, " %s\n", v) } } return buf.Bytes(), nil } func Test_Marshaler(t *testing.T) { const expected = `- hello-world ` // sanity check var l []string if err := yaml.Unmarshal([]byte(expected), &l); err != nil { t.Fatalf("failed to parse string: %s", err) } buf, err := yaml.Marshal(tMarshal{"hello-world"}) if err != nil { t.Fatalf("failed to marshal: %s", err) } if string(buf) != expected { t.Fatalf("expected '%s', got '%s'", expected, buf) } t.Logf("%s", buf) } type marshalContext struct{} func (c *marshalContext) MarshalYAML(ctx context.Context) ([]byte, error) { v, ok := ctx.Value("k").(int) if !ok { return nil, errors.New("cannot get valid context") } if v != 1 { return nil, errors.New("cannot get valid context") } return []byte("1"), nil } func Test_MarshalerContext(t *testing.T) { ctx := context.WithValue(context.Background(), "k", 1) bytes, err := yaml.MarshalContext(ctx, &marshalContext{}) if err != nil { t.Fatalf("%+v", err) } if string(bytes) != "1\n" { t.Fatalf("failed marshal: %q", string(bytes)) } } type SlowMarshaler struct { A string B int } type FastMarshaler struct { A string B int } type TextMarshaler int64 type TextMarshalerContainer struct { Field TextMarshaler `yaml:"field"` } func (v SlowMarshaler) MarshalYAML() ([]byte, error) { var buf bytes.Buffer buf.WriteString("tags:\n") buf.WriteString("- slow-marshaler\n") buf.WriteString("a: " + v.A + "\n") buf.WriteString("b: " + strconv.FormatInt(int64(v.B), 10) + "\n") return buf.Bytes(), nil } func (v FastMarshaler) MarshalYAML() (interface{}, error) { return yaml.MapSlice{ {"tags", []string{"fast-marshaler"}}, {"a", v.A}, {"b", v.B}, }, nil } func (t TextMarshaler) MarshalText() ([]byte, error) { return []byte(strconv.FormatInt(int64(t), 8)), nil } func ExampleMarshal() { var slow SlowMarshaler slow.A = "Hello slow poke" slow.B = 100 buf, err := yaml.Marshal(slow) if err != nil { panic(err.Error()) } fmt.Println(string(buf)) var fast FastMarshaler fast.A = "Hello speed demon" fast.B = 100 buf, err = yaml.Marshal(fast) if err != nil { panic(err.Error()) } fmt.Println(string(buf)) text := TextMarshalerContainer{ Field: 11, } buf, err = yaml.Marshal(text) if err != nil { panic(err.Error()) } fmt.Println(string(buf)) // OUTPUT: // tags: // - slow-marshaler // a: Hello slow poke // b: 100 // // tags: // - fast-marshaler // a: Hello speed demon // b: 100 // // field: "13" } func TestIssue356(t *testing.T) { tests := map[string]struct { in string }{ "content on first line": { in: `args: - | key: nest1: something nest2: nest2a: b `, }, "empty first line": { in: `args: - | key: nest1: something nest2: nest2a: b `, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { f, err := parser.ParseBytes([]byte(test.in), 0) if err != nil { t.Fatalf("parse: %v", err) } got := f.String() if test.in != got { t.Fatalf("failed to encode.\nexpected:\n%s\nbut got:\n%s\n", test.in, got) } }) } } func TestMarshalIndentWithMultipleText(t *testing.T) { tests := []struct { name string input map[string]interface{} indent yaml.EncodeOption want string }{ { name: "depth1", input: map[string]interface{}{ "key": []string{`line1 line2 line3`}, }, indent: yaml.Indent(2), want: `key: - |- line1 line2 line3 `, }, { name: "depth2", input: map[string]interface{}{ "key": map[string]interface{}{ "key2": []string{`line1 line2 line3`}, }, }, indent: yaml.Indent(2), want: `key: key2: - |- line1 line2 line3 `, }, { name: "raw string new lines", input: map[string]interface{}{ "key": "line1\nline2\nline3", }, indent: yaml.Indent(4), want: `key: |- line1 line2 line3 `, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { b, err := yaml.MarshalWithOptions(tt.input, tt.indent) if err != nil { t.Fatalf("failed to marshal yaml: %v", err) } got := string(b) if tt.want != got { t.Fatalf("failed to encode.\nexpected:\n%s\nbut got:\n%s\n", tt.want, got) } }) } } type bytesMarshaler struct{} func (b *bytesMarshaler) MarshalYAML() ([]byte, error) { return yaml.Marshal(map[string]interface{}{"d": "foo"}) } func TestBytesMarshaler(t *testing.T) { b, err := yaml.Marshal(map[string]interface{}{ "a": map[string]interface{}{ "b": map[string]interface{}{ "c": &bytesMarshaler{}, }, }, }) if err != nil { t.Fatal(err) } expected := ` a: b: c: d: foo ` got := "\n" + string(b) if expected != got { t.Fatalf("failed to encode. expected %s but got %s", expected, got) } } type customMapSliceOneItemMarshaler struct{} func (m *customMapSliceOneItemMarshaler) MarshalYAML() ([]byte, error) { var v yaml.MapSlice v = append(v, yaml.MapItem{"a", "b"}) return yaml.Marshal(v) } type customMapSliceTwoItemMarshaler struct{} func (m *customMapSliceTwoItemMarshaler) MarshalYAML() ([]byte, error) { var v yaml.MapSlice v = append(v, yaml.MapItem{"a", "b"}) v = append(v, yaml.MapItem{"b", "c"}) return yaml.Marshal(v) } func TestCustomMapSliceMarshaler(t *testing.T) { type T struct { A *customMapSliceOneItemMarshaler `yaml:"a"` B *customMapSliceTwoItemMarshaler `yaml:"b"` } b, err := yaml.Marshal(&T{ A: &customMapSliceOneItemMarshaler{}, B: &customMapSliceTwoItemMarshaler{}, }) if err != nil { t.Fatal(err) } expected := ` a: a: b b: a: b b: c ` got := "\n" + string(b) if expected != got { t.Fatalf("failed to encode. expected %s but got %s", expected, got) } } type Issue174 struct { K string V []int } func (v Issue174) MarshalYAML() ([]byte, error) { return yaml.MarshalWithOptions(map[string][]int{v.K: v.V}, yaml.Flow(true)) } func TestIssue174(t *testing.T) { b, err := yaml.Marshal(Issue174{"00:00:00-23:59:59", []int{1, 2, 3}}) if err != nil { t.Fatal(err) } got := strings.TrimSuffix(string(b), "\n") if got != `{"00:00:00-23:59:59": [1, 2, 3]}` { t.Fatalf("failed to encode: %q", got) } } func TestIssue259(t *testing.T) { type AnchorValue struct { Foo uint64 Bar string } type Value struct { Baz string `yaml:"baz"` Value *AnchorValue `yaml:"value,anchor"` } type Schema struct { Values []*Value } schema := Schema{} anchorValue := AnchorValue{Foo: 3, Bar: "bar"} schema.Values = []*Value{ {Baz: "xxx", Value: &anchorValue}, {Baz: "yyy", Value: &anchorValue}, {Baz: "zzz", Value: &anchorValue}, } b, err := yaml.Marshal(schema) if err != nil { t.Fatal(err) } expected := ` values: - baz: xxx value: &value foo: 3 bar: bar - baz: yyy value: *value - baz: zzz value: *value ` if strings.TrimPrefix(expected, "\n") != string(b) { t.Fatalf("failed to encode: got = %s", string(b)) } } func TestTagMarshalling(t *testing.T) { tests := []struct { name string input string }{ {name: "scalar", input: "a: !mytag 1"}, {name: "mapping", input: ` a: !mytag b: 2`}, {name: "sequence", input: ` a: !mytag - 1 - 2 - 3`}, {name: "anchor before tag", input: ` a: &anc !mytag - 1 - 2 - 3`}, {name: "flow mapping", input: "a: !mytag {b: 2}"}, {name: "flow sequence", input: "a: !mytag [1, 2, 3]"}, {name: "explicit type", input: "a: !!timestamp test"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { res, _ := parser.ParseBytes([]byte(tt.input), 0) result, err := yaml.Marshal(res.Docs[0]) if err != nil { t.Fatal(err) } expected := strings.TrimSpace(tt.input) output := strings.TrimSpace(string(result)) if expected != output { t.Fatalf("input is not equal to output.\n\nexpected:\n%v\n actual:\n%v", expected, output) } }) } } func ptr[T any](v T) *T { return &v } goccy-go-yaml-52dacb8/error.go000066400000000000000000000051161501576637100163510ustar00rootroot00000000000000package yaml import ( "fmt" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" ) var ( ErrInvalidQuery = errors.New("invalid query") ErrInvalidPath = errors.New("invalid path instance") ErrInvalidPathString = errors.New("invalid path string") ErrNotFoundNode = errors.New("node not found") ErrUnknownCommentPositionType = errors.New("unknown comment position type") ErrInvalidCommentMapValue = errors.New("invalid comment map value. it must be not nil value") ErrDecodeRequiredPointerType = errors.New("required pointer type value") ErrExceededMaxDepth = errors.New("exceeded max depth") FormatErrorWithToken = errors.FormatError ) type ( SyntaxError = errors.SyntaxError TypeError = errors.TypeError OverflowError = errors.OverflowError DuplicateKeyError = errors.DuplicateKeyError UnknownFieldError = errors.UnknownFieldError UnexpectedNodeTypeError = errors.UnexpectedNodeTypeError Error = errors.Error ) func ErrUnsupportedHeadPositionType(node ast.Node) error { return fmt.Errorf("unsupported comment head position for %s", node.Type()) } func ErrUnsupportedLinePositionType(node ast.Node) error { return fmt.Errorf("unsupported comment line position for %s", node.Type()) } func ErrUnsupportedFootPositionType(node ast.Node) error { return fmt.Errorf("unsupported comment foot position for %s", node.Type()) } // IsInvalidQueryError whether err is ErrInvalidQuery or not. func IsInvalidQueryError(err error) bool { return errors.Is(err, ErrInvalidQuery) } // IsInvalidPathError whether err is ErrInvalidPath or not. func IsInvalidPathError(err error) bool { return errors.Is(err, ErrInvalidPath) } // IsInvalidPathStringError whether err is ErrInvalidPathString or not. func IsInvalidPathStringError(err error) bool { return errors.Is(err, ErrInvalidPathString) } // IsNotFoundNodeError whether err is ErrNotFoundNode or not. func IsNotFoundNodeError(err error) bool { return errors.Is(err, ErrNotFoundNode) } // IsInvalidTokenTypeError whether err is ast.ErrInvalidTokenType or not. func IsInvalidTokenTypeError(err error) bool { return errors.Is(err, ast.ErrInvalidTokenType) } // IsInvalidAnchorNameError whether err is ast.ErrInvalidAnchorName or not. func IsInvalidAnchorNameError(err error) bool { return errors.Is(err, ast.ErrInvalidAnchorName) } // IsInvalidAliasNameError whether err is ast.ErrInvalidAliasName or not. func IsInvalidAliasNameError(err error) bool { return errors.Is(err, ast.ErrInvalidAliasName) } goccy-go-yaml-52dacb8/fuzz_test.go000066400000000000000000000015451501576637100172570ustar00rootroot00000000000000package yaml_test import ( "strings" "testing" "github.com/goccy/go-yaml" ) func FuzzUnmarshalToMap(f *testing.F) { const validYAML = ` id: 1 message: Hello, World verified: true ` invalidYAML := []string{ "0::", "{0", "*-0", ">\n>", "&{0", "0_", "0\n:", "0\n-", "0\n0", "0\n0\n", "0\n0\n0", "0\n0\n0\n", "0\n0\n0\n0", "0\n0\n0\n0\n", "0\n0\n0\n0\n0", "0\n0\n0\n0\n0\n", "0\n0\n0\n0\n0\n0", "0\n0\n0\n0\n0\n0\n", "", "00A: 0000A", "{\"000\":0000A,", } f.Add([]byte(validYAML)) for _, s := range invalidYAML { f.Add([]byte(s)) f.Add([]byte(validYAML + s)) f.Add([]byte(s + validYAML)) f.Add([]byte(s + validYAML + s)) f.Add([]byte(strings.Repeat(s, 3))) } f.Fuzz(func(t *testing.T, src []byte) { v := map[string]any{} if err := yaml.Unmarshal(src, &v); err != nil { t.Log(err.Error()) } }) } goccy-go-yaml-52dacb8/go.mod000066400000000000000000000000531501576637100157720ustar00rootroot00000000000000module github.com/goccy/go-yaml go 1.21.0 goccy-go-yaml-52dacb8/go.sum000066400000000000000000000000001501576637100160070ustar00rootroot00000000000000goccy-go-yaml-52dacb8/internal/000077500000000000000000000000001501576637100165025ustar00rootroot00000000000000goccy-go-yaml-52dacb8/internal/errors/000077500000000000000000000000001501576637100200165ustar00rootroot00000000000000goccy-go-yaml-52dacb8/internal/errors/error.go000066400000000000000000000131531501576637100215010ustar00rootroot00000000000000package errors import ( "errors" "fmt" "reflect" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/printer" "github.com/goccy/go-yaml/token" ) var ( As = errors.As Is = errors.Is New = errors.New ) const ( defaultFormatColor = false defaultIncludeSource = true ) type Error interface { error GetToken() *token.Token GetMessage() string FormatError(bool, bool) string } var ( _ Error = new(SyntaxError) _ Error = new(TypeError) _ Error = new(OverflowError) _ Error = new(DuplicateKeyError) _ Error = new(UnknownFieldError) _ Error = new(UnexpectedNodeTypeError) ) type SyntaxError struct { Message string Token *token.Token } type TypeError struct { DstType reflect.Type SrcType reflect.Type StructFieldName *string Token *token.Token } type OverflowError struct { DstType reflect.Type SrcNum string Token *token.Token } type DuplicateKeyError struct { Message string Token *token.Token } type UnknownFieldError struct { Message string Token *token.Token } type UnexpectedNodeTypeError struct { Actual ast.NodeType Expected ast.NodeType Token *token.Token } // ErrSyntax create syntax error instance with message and token func ErrSyntax(msg string, tk *token.Token) *SyntaxError { return &SyntaxError{ Message: msg, Token: tk, } } // ErrOverflow creates an overflow error instance with message and a token. func ErrOverflow(dstType reflect.Type, num string, tk *token.Token) *OverflowError { return &OverflowError{ DstType: dstType, SrcNum: num, Token: tk, } } // ErrTypeMismatch cerates an type mismatch error instance with token. func ErrTypeMismatch(dstType, srcType reflect.Type, token *token.Token) *TypeError { return &TypeError{ DstType: dstType, SrcType: srcType, Token: token, } } // ErrDuplicateKey creates an duplicate key error instance with token. func ErrDuplicateKey(msg string, tk *token.Token) *DuplicateKeyError { return &DuplicateKeyError{ Message: msg, Token: tk, } } // ErrUnknownField creates an unknown field error instance with token. func ErrUnknownField(msg string, tk *token.Token) *UnknownFieldError { return &UnknownFieldError{ Message: msg, Token: tk, } } func ErrUnexpectedNodeType(actual, expected ast.NodeType, tk *token.Token) *UnexpectedNodeTypeError { return &UnexpectedNodeTypeError{ Actual: actual, Expected: expected, Token: tk, } } func (e *SyntaxError) GetMessage() string { return e.Message } func (e *SyntaxError) GetToken() *token.Token { return e.Token } func (e *SyntaxError) Error() string { return e.FormatError(defaultFormatColor, defaultIncludeSource) } func (e *SyntaxError) FormatError(colored, inclSource bool) string { return FormatError(e.Message, e.Token, colored, inclSource) } func (e *OverflowError) GetMessage() string { return e.msg() } func (e *OverflowError) GetToken() *token.Token { return e.Token } func (e *OverflowError) Error() string { return e.FormatError(defaultFormatColor, defaultIncludeSource) } func (e *OverflowError) FormatError(colored, inclSource bool) string { return FormatError(e.msg(), e.Token, colored, inclSource) } func (e *OverflowError) msg() string { return fmt.Sprintf("cannot unmarshal %s into Go value of type %s ( overflow )", e.SrcNum, e.DstType) } func (e *TypeError) msg() string { if e.StructFieldName != nil { return fmt.Sprintf("cannot unmarshal %s into Go struct field %s of type %s", e.SrcType, *e.StructFieldName, e.DstType) } return fmt.Sprintf("cannot unmarshal %s into Go value of type %s", e.SrcType, e.DstType) } func (e *TypeError) GetMessage() string { return e.msg() } func (e *TypeError) GetToken() *token.Token { return e.Token } func (e *TypeError) Error() string { return e.FormatError(defaultFormatColor, defaultIncludeSource) } func (e *TypeError) FormatError(colored, inclSource bool) string { return FormatError(e.msg(), e.Token, colored, inclSource) } func (e *DuplicateKeyError) GetMessage() string { return e.Message } func (e *DuplicateKeyError) GetToken() *token.Token { return e.Token } func (e *DuplicateKeyError) Error() string { return e.FormatError(defaultFormatColor, defaultIncludeSource) } func (e *DuplicateKeyError) FormatError(colored, inclSource bool) string { return FormatError(e.Message, e.Token, colored, inclSource) } func (e *UnknownFieldError) GetMessage() string { return e.Message } func (e *UnknownFieldError) GetToken() *token.Token { return e.Token } func (e *UnknownFieldError) Error() string { return e.FormatError(defaultFormatColor, defaultIncludeSource) } func (e *UnknownFieldError) FormatError(colored, inclSource bool) string { return FormatError(e.Message, e.Token, colored, inclSource) } func (e *UnexpectedNodeTypeError) GetMessage() string { return e.msg() } func (e *UnexpectedNodeTypeError) GetToken() *token.Token { return e.Token } func (e *UnexpectedNodeTypeError) Error() string { return e.FormatError(defaultFormatColor, defaultIncludeSource) } func (e *UnexpectedNodeTypeError) FormatError(colored, inclSource bool) string { return FormatError(e.msg(), e.Token, colored, inclSource) } func (e *UnexpectedNodeTypeError) msg() string { return fmt.Sprintf("%s was used where %s is expected", e.Actual.YAMLName(), e.Expected.YAMLName()) } func FormatError(errMsg string, token *token.Token, colored, inclSource bool) string { var pp printer.Printer if token == nil { return pp.PrintErrorMessage(errMsg, colored) } pos := fmt.Sprintf("[%d:%d] ", token.Position.Line, token.Position.Column) msg := pp.PrintErrorMessage(fmt.Sprintf("%s%s", pos, errMsg), colored) if inclSource { msg += "\n" + pp.PrintErrorToken(token, colored) } return msg } goccy-go-yaml-52dacb8/internal/format/000077500000000000000000000000001501576637100177725ustar00rootroot00000000000000goccy-go-yaml-52dacb8/internal/format/format.go000066400000000000000000000307651501576637100216240ustar00rootroot00000000000000package format import ( "strings" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/token" ) func FormatNodeWithResolvedAlias(n ast.Node, anchorNodeMap map[string]ast.Node) string { tk := getFirstToken(n) if tk == nil { return "" } formatter := newFormatter(tk, hasComment(n)) formatter.anchorNodeMap = anchorNodeMap return formatter.format(n) } func FormatNode(n ast.Node) string { tk := getFirstToken(n) if tk == nil { return "" } return newFormatter(tk, hasComment(n)).format(n) } func FormatFile(file *ast.File) string { if len(file.Docs) == 0 { return "" } tk := getFirstToken(file.Docs[0]) if tk == nil { return "" } return newFormatter(tk, hasCommentFile(file)).formatFile(file) } func hasCommentFile(f *ast.File) bool { for _, doc := range f.Docs { if hasComment(doc.Body) { return true } } return false } func hasComment(n ast.Node) bool { if n == nil { return false } switch nn := n.(type) { case *ast.DocumentNode: return hasComment(nn.Body) case *ast.NullNode: return nn.Comment != nil case *ast.BoolNode: return nn.Comment != nil case *ast.IntegerNode: return nn.Comment != nil case *ast.FloatNode: return nn.Comment != nil case *ast.StringNode: return nn.Comment != nil case *ast.InfinityNode: return nn.Comment != nil case *ast.NanNode: return nn.Comment != nil case *ast.LiteralNode: return nn.Comment != nil case *ast.DirectiveNode: if nn.Comment != nil { return true } for _, value := range nn.Values { if hasComment(value) { return true } } case *ast.TagNode: if nn.Comment != nil { return true } return hasComment(nn.Value) case *ast.MappingNode: if nn.Comment != nil || nn.FootComment != nil { return true } for _, value := range nn.Values { if value.Comment != nil || value.FootComment != nil { return true } if hasComment(value.Key) { return true } if hasComment(value.Value) { return true } } case *ast.MappingKeyNode: return nn.Comment != nil case *ast.MergeKeyNode: return nn.Comment != nil case *ast.SequenceNode: if nn.Comment != nil || nn.FootComment != nil { return true } for _, entry := range nn.Entries { if entry.Comment != nil || entry.HeadComment != nil || entry.LineComment != nil { return true } if hasComment(entry.Value) { return true } } case *ast.AnchorNode: if nn.Comment != nil { return true } if hasComment(nn.Name) || hasComment(nn.Value) { return true } case *ast.AliasNode: if nn.Comment != nil { return true } if hasComment(nn.Value) { return true } } return false } func getFirstToken(n ast.Node) *token.Token { if n == nil { return nil } switch nn := n.(type) { case *ast.DocumentNode: if nn.Start != nil { return nn.Start } return getFirstToken(nn.Body) case *ast.NullNode: return nn.Token case *ast.BoolNode: return nn.Token case *ast.IntegerNode: return nn.Token case *ast.FloatNode: return nn.Token case *ast.StringNode: return nn.Token case *ast.InfinityNode: return nn.Token case *ast.NanNode: return nn.Token case *ast.LiteralNode: return nn.Start case *ast.DirectiveNode: return nn.Start case *ast.TagNode: return nn.Start case *ast.MappingNode: if nn.IsFlowStyle { return nn.Start } if len(nn.Values) == 0 { return nn.Start } return getFirstToken(nn.Values[0].Key) case *ast.MappingKeyNode: return nn.Start case *ast.MergeKeyNode: return nn.Token case *ast.SequenceNode: return nn.Start case *ast.AnchorNode: return nn.Start case *ast.AliasNode: return nn.Start } return nil } type Formatter struct { existsComment bool tokenToOriginMap map[*token.Token]string anchorNodeMap map[string]ast.Node } func newFormatter(tk *token.Token, existsComment bool) *Formatter { tokenToOriginMap := make(map[*token.Token]string) for tk.Prev != nil { tk = tk.Prev } tokenToOriginMap[tk] = tk.Origin var origin string for tk.Next != nil { tk = tk.Next if tk.Type == token.CommentType { origin += strings.Repeat("\n", strings.Count(normalizeNewLineChars(tk.Origin), "\n")) continue } origin += tk.Origin tokenToOriginMap[tk] = origin origin = "" } return &Formatter{ existsComment: existsComment, tokenToOriginMap: tokenToOriginMap, } } func getIndentNumByFirstLineToken(tk *token.Token) int { defaultIndent := tk.Position.Column - 1 // key: value // ^ // next if tk.Type == token.SequenceEntryType { // If the current token is the sequence entry. // the indent is calculated from the column value of the current token. return defaultIndent } // key: value // ^ // next if tk.Next != nil && tk.Next.Type == token.MappingValueType { // If the current token is the key in the mapping-value, // the indent is calculated from the column value of the current token. return defaultIndent } if tk.Prev == nil { return defaultIndent } prev := tk.Prev // key: value // ^ // prev if prev.Type == token.MappingValueType { // If the current token is the value in the mapping-value, // the indent is calculated from the column value of the key two steps back. if prev.Prev == nil { return defaultIndent } return prev.Prev.Position.Column - 1 } // - value // ^ // prev if prev.Type == token.SequenceEntryType { // If the value is not a mapping-value and the previous token was a sequence entry, // the indent is calculated using the column value of the sequence entry token. return prev.Position.Column - 1 } return defaultIndent } func (f *Formatter) format(n ast.Node) string { return f.trimSpacePrefix( f.trimIndentSpace( getIndentNumByFirstLineToken(getFirstToken(n)), f.trimNewLineCharPrefix(f.formatNode(n)), ), ) } func (f *Formatter) formatFile(file *ast.File) string { if len(file.Docs) == 0 { return "" } var ret string for _, doc := range file.Docs { ret += f.formatDocument(doc) } return ret } func (f *Formatter) origin(tk *token.Token) string { if tk == nil { return "" } if f.existsComment { return tk.Origin } return f.tokenToOriginMap[tk] } func (f *Formatter) formatDocument(n *ast.DocumentNode) string { return f.origin(n.Start) + f.formatNode(n.Body) + f.origin(n.End) } func (f *Formatter) formatNull(n *ast.NullNode) string { return f.origin(n.Token) + f.formatCommentGroup(n.Comment) } func (f *Formatter) formatString(n *ast.StringNode) string { return f.origin(n.Token) + f.formatCommentGroup(n.Comment) } func (f *Formatter) formatInteger(n *ast.IntegerNode) string { return f.origin(n.Token) + f.formatCommentGroup(n.Comment) } func (f *Formatter) formatFloat(n *ast.FloatNode) string { return f.origin(n.Token) + f.formatCommentGroup(n.Comment) } func (f *Formatter) formatBool(n *ast.BoolNode) string { return f.origin(n.Token) + f.formatCommentGroup(n.Comment) } func (f *Formatter) formatInfinity(n *ast.InfinityNode) string { return f.origin(n.Token) + f.formatCommentGroup(n.Comment) } func (f *Formatter) formatNan(n *ast.NanNode) string { return f.origin(n.Token) + f.formatCommentGroup(n.Comment) } func (f *Formatter) formatLiteral(n *ast.LiteralNode) string { return f.origin(n.Start) + f.formatCommentGroup(n.Comment) + f.origin(n.Value.Token) } func (f *Formatter) formatMergeKey(n *ast.MergeKeyNode) string { return f.origin(n.Token) } func (f *Formatter) formatMappingValue(n *ast.MappingValueNode) string { return f.formatCommentGroup(n.Comment) + f.origin(n.Key.GetToken()) + ":" + f.formatCommentGroup(n.Key.GetComment()) + f.formatNode(n.Value) + f.formatCommentGroup(n.FootComment) } func (f *Formatter) formatDirective(n *ast.DirectiveNode) string { ret := f.origin(n.Start) + f.formatNode(n.Name) for _, val := range n.Values { ret += f.formatNode(val) } return ret } func (f *Formatter) formatMapping(n *ast.MappingNode) string { var ret string if n.IsFlowStyle { ret = f.origin(n.Start) } ret += f.formatCommentGroup(n.Comment) for _, value := range n.Values { if value.CollectEntry != nil { ret += f.origin(value.CollectEntry) } ret += f.formatMappingValue(value) } if n.IsFlowStyle { ret += f.origin(n.End) } return ret } func (f *Formatter) formatTag(n *ast.TagNode) string { return f.origin(n.Start) + f.formatNode(n.Value) } func (f *Formatter) formatMappingKey(n *ast.MappingKeyNode) string { return f.origin(n.Start) + f.formatNode(n.Value) } func (f *Formatter) formatSequence(n *ast.SequenceNode) string { var ret string if n.IsFlowStyle { ret = f.origin(n.Start) } if n.Comment != nil { // add head comment. ret += f.formatCommentGroup(n.Comment) } for _, entry := range n.Entries { ret += f.formatNode(entry) } if n.IsFlowStyle { ret += f.origin(n.End) } ret += f.formatCommentGroup(n.FootComment) return ret } func (f *Formatter) formatSequenceEntry(n *ast.SequenceEntryNode) string { return f.formatCommentGroup(n.HeadComment) + f.origin(n.Start) + f.formatCommentGroup(n.LineComment) + f.formatNode(n.Value) } func (f *Formatter) formatAnchor(n *ast.AnchorNode) string { return f.origin(n.Start) + f.formatNode(n.Name) + f.formatNode(n.Value) } func (f *Formatter) formatAlias(n *ast.AliasNode) string { if f.anchorNodeMap != nil { anchorName := n.Value.GetToken().Value node := f.anchorNodeMap[anchorName] if node != nil { formatted := f.formatNode(node) // If formatted text contains newline characters, indentation needs to be considered. if strings.Contains(formatted, "\n") { // If the first character is not a newline, the first line should be output without indentation. isIgnoredFirstLine := !strings.HasPrefix(formatted, "\n") formatted = f.addIndentSpace(n.GetToken().Position.IndentNum, formatted, isIgnoredFirstLine) } return formatted } } return f.origin(n.Start) + f.formatNode(n.Value) } func (f *Formatter) formatNode(n ast.Node) string { switch nn := n.(type) { case *ast.DocumentNode: return f.formatDocument(nn) case *ast.NullNode: return f.formatNull(nn) case *ast.BoolNode: return f.formatBool(nn) case *ast.IntegerNode: return f.formatInteger(nn) case *ast.FloatNode: return f.formatFloat(nn) case *ast.StringNode: return f.formatString(nn) case *ast.InfinityNode: return f.formatInfinity(nn) case *ast.NanNode: return f.formatNan(nn) case *ast.LiteralNode: return f.formatLiteral(nn) case *ast.DirectiveNode: return f.formatDirective(nn) case *ast.TagNode: return f.formatTag(nn) case *ast.MappingNode: return f.formatMapping(nn) case *ast.MappingKeyNode: return f.formatMappingKey(nn) case *ast.MappingValueNode: return f.formatMappingValue(nn) case *ast.MergeKeyNode: return f.formatMergeKey(nn) case *ast.SequenceNode: return f.formatSequence(nn) case *ast.SequenceEntryNode: return f.formatSequenceEntry(nn) case *ast.AnchorNode: return f.formatAnchor(nn) case *ast.AliasNode: return f.formatAlias(nn) } return "" } func (f *Formatter) formatCommentGroup(g *ast.CommentGroupNode) string { if g == nil { return "" } var ret string for _, cm := range g.Comments { ret += f.formatComment(cm) } return ret } func (f *Formatter) formatComment(n *ast.CommentNode) string { if n == nil { return "" } return n.Token.Origin } // nolint: unused func (f *Formatter) formatIndent(col int) string { if col <= 1 { return "" } return strings.Repeat(" ", col-1) } func (f *Formatter) trimNewLineCharPrefix(v string) string { return strings.TrimLeftFunc(v, func(r rune) bool { return r == '\n' || r == '\r' }) } func (f *Formatter) trimSpacePrefix(v string) string { return strings.TrimLeftFunc(v, func(r rune) bool { return r == ' ' }) } func (f *Formatter) trimIndentSpace(trimIndentNum int, v string) string { if trimIndentNum == 0 { return v } lines := strings.Split(normalizeNewLineChars(v), "\n") out := make([]string, 0, len(lines)) for _, line := range lines { var cnt int out = append(out, strings.TrimLeftFunc(line, func(r rune) bool { cnt++ return r == ' ' && cnt <= trimIndentNum })) } return strings.Join(out, "\n") } func (f *Formatter) addIndentSpace(indentNum int, v string, isIgnoredFirstLine bool) string { if indentNum == 0 { return v } indent := strings.Repeat(" ", indentNum) lines := strings.Split(normalizeNewLineChars(v), "\n") out := make([]string, 0, len(lines)) for idx, line := range lines { if line == "" || (isIgnoredFirstLine && idx == 0) { out = append(out, line) continue } out = append(out, indent+line) } return strings.Join(out, "\n") } // normalizeNewLineChars normalize CRLF and CR to LF. func normalizeNewLineChars(v string) string { return strings.ReplaceAll(strings.ReplaceAll(v, "\r\n", "\n"), "\r", "\n") } goccy-go-yaml-52dacb8/lexer/000077500000000000000000000000001501576637100160055ustar00rootroot00000000000000goccy-go-yaml-52dacb8/lexer/lexer.go000066400000000000000000000005641501576637100174600ustar00rootroot00000000000000package lexer import ( "io" "github.com/goccy/go-yaml/scanner" "github.com/goccy/go-yaml/token" ) // Tokenize split to token instances from string func Tokenize(src string) token.Tokens { var s scanner.Scanner s.Init(src) var tokens token.Tokens for { subTokens, err := s.Scan() if err == io.EOF { break } tokens.Add(subTokens...) } return tokens } goccy-go-yaml-52dacb8/lexer/lexer_test.go000066400000000000000000002322461501576637100205230ustar00rootroot00000000000000package lexer_test import ( "sort" "testing" "github.com/goccy/go-yaml/lexer" "github.com/goccy/go-yaml/token" ) func TestTokenize(t *testing.T) { tests := []struct { YAML string Tokens token.Tokens }{ { YAML: `null `, Tokens: token.Tokens{ { Type: token.NullType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "null", Origin: "null\n ", }, }, }, { YAML: `0_`, Tokens: token.Tokens{ { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "0_", Origin: "0_", }, }, }, { YAML: `"hello\tworld"`, Tokens: token.Tokens{ { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "hello\tworld", Origin: `"hello\tworld"`, }, }, }, { YAML: `0x_1A_2B_3C`, Tokens: token.Tokens{ { Type: token.HexIntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "0x_1A_2B_3C", Origin: "0x_1A_2B_3C", }, }, }, { YAML: `+0b1010`, Tokens: token.Tokens{ { Type: token.BinaryIntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "+0b1010", Origin: "+0b1010", }, }, }, { YAML: `0100`, Tokens: token.Tokens{ { Type: token.OctetIntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "0100", Origin: "0100", }, }, }, { YAML: `0o10`, Tokens: token.Tokens{ { Type: token.OctetIntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "0o10", Origin: "0o10", }, }, }, { YAML: `0.123e+123`, Tokens: token.Tokens{ { Type: token.FloatType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "0.123e+123", Origin: "0.123e+123", }, }, }, { YAML: `{} `, Tokens: token.Tokens{ { Type: token.MappingStartType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: "{", Origin: "{", }, { Type: token.MappingEndType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: "}", Origin: "}", }, }, }, { YAML: `v: hi`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "hi", Origin: " hi", }, }, }, { YAML: `v: a`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", // nolint: gci Origin: " a", }, }, }, { YAML: `v: "true"`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "true", Origin: " \"true\"", }, }, }, { YAML: `v: "false"`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "false", Origin: " \"false\"", }, }, }, { YAML: `v: true`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.BoolType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "true", Origin: " true", }, }, }, { YAML: `v: false`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.BoolType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "false", Origin: " false", }, }, }, { YAML: `v: 10`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "10", Origin: " 10", }, }, }, { YAML: `v: -10`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "-10", Origin: " -10", }, }, }, { YAML: `v: 42`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "42", Origin: " 42", }, }, }, { YAML: `v: 4294967296`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "4294967296", Origin: " 4294967296", }, }, }, { YAML: `v: "10"`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "10", Origin: " \"10\"", }, }, }, { YAML: `v: 0.1`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FloatType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "0.1", Origin: " 0.1", }, }, }, { YAML: `v: 0.99`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FloatType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "0.99", Origin: " 0.99", }, }, }, { YAML: `v: -0.1`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FloatType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "-0.1", Origin: " -0.1", }, }, }, { YAML: `v: .inf`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.InfinityType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: ".inf", Origin: " .inf", }, }, }, { YAML: `v: -.inf`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.InfinityType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "-.inf", Origin: " -.inf", }, }, }, { YAML: `v: .nan`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.NanType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: ".nan", Origin: " .nan", }, }, }, { YAML: ` a: "bbb \ ccc ddd eee\n\ \ \ fff ggg\nhhh iii\n jjj kkk " `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "bbb ccc\nddd eee\n fff ggg\nhhh iii\n jjj kkk ", Origin: "\n \"bbb \\\n ccc\n\n ddd eee\\n\\\n \\ \\ fff ggg\\nhhh iii\\n\n jjj kkk\n \"", }, }, }, { YAML: `v: null`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.NullType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "null", Origin: " null", }, }, }, { YAML: `v: ""`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "v", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "", Origin: " \"\"", }, }, }, { YAML: ` v: - A - B `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "\nv", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SequenceEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: "-", Origin: "\n-", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "A", Origin: " A\n", }, { Type: token.SequenceEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: "-", Origin: "-", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "B", Origin: " B", }, }, }, { YAML: ` v: - A - |- B C `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "\nv", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SequenceEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: "-", Origin: "\n-", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "A", Origin: " A\n", }, { Type: token.SequenceEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: "-", Origin: "-", }, { Type: token.LiteralType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: "|-", Origin: " |-\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "B\nC", Origin: " B\n C\n", }, }, }, { YAML: ` v: - A - 1 - B: - 2 - 3 `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "v", Origin: "\nv", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SequenceEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: "-", Origin: "\n-", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "A", Origin: " A\n", }, { Type: token.SequenceEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: "-", Origin: "-", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1", Origin: " 1\n", }, { Type: token.SequenceEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: "-", Origin: "-", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "B", Origin: " B", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SequenceEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: "-", Origin: "\n -", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "2", Origin: " 2\n ", }, { Type: token.SequenceEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: "-", Origin: "-", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "3", Origin: " 3", }, }, }, { YAML: ` a: b: c `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "b", Origin: "\n b", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "c", Origin: " c", }, }, }, { YAML: `a: '-'`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SingleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "-", Origin: " '-'", }, }, }, { YAML: `123`, Tokens: token.Tokens{ { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "123", Origin: "123", }, }, }, { YAML: `hello: world `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "hello", Origin: "hello", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "world", Origin: " world", }, }, }, { YAML: `a: null`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.NullType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "null", Origin: " null", }, }, }, { YAML: `a: {x: 1}`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.MappingStartType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: "{", Origin: " {", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "x", Origin: "x", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1", Origin: " 1", }, { Type: token.MappingEndType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: "}", Origin: "}", }, }, }, { YAML: `a: [1, 2]`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SequenceStartType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: "[", Origin: " [", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1", Origin: "1", }, { Type: token.CollectEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: ",", Origin: ",", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "2", Origin: " 2", }, { Type: token.SequenceEndType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: "]", Origin: "]", }, }, }, { YAML: ` t2: 2018-01-09T10:40:47Z t4: 2098-01-09T10:40:47Z `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "t2", Origin: "\nt2", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "2018-01-09T10:40:47Z", Origin: " 2018-01-09T10:40:47Z\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "t4", Origin: "t4", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "2098-01-09T10:40:47Z", Origin: " 2098-01-09T10:40:47Z", }, }, }, { YAML: `a: {b: c, d: e}`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.MappingStartType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: "{", Origin: " {", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "b", Origin: "b", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "c", Origin: " c", }, { Type: token.CollectEntryType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: ",", Origin: ",", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "d", Origin: " d", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "e", Origin: " e", }, { Type: token.MappingEndType, CharacterType: token.CharacterTypeIndicator, Indicator: token.FlowCollectionIndicator, Value: "}", Origin: "}", }, }, }, { YAML: `a: 3s`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "3s", Origin: " 3s", }, }, }, { YAML: `a: `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "", Origin: " ", }, }, }, { YAML: `a: "1:1"`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "1:1", Origin: " \"1:1\"", }, }, }, { YAML: `a: "\0"`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "\x00", Origin: " \"\\0\"", }, }, }, { YAML: `a: !!binary gIGC`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.TagType, CharacterType: token.CharacterTypeIndicator, Indicator: token.NodePropertyIndicator, Value: "!!binary", Origin: " !!binary ", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "gIGC", Origin: "gIGC", }, }, }, { YAML: ` a: !!binary | kJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ CQ `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.TagType, CharacterType: token.CharacterTypeIndicator, Indicator: token.NodePropertyIndicator, Value: "!!binary", Origin: " !!binary ", }, { Type: token.LiteralType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: "|", Origin: "|\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "kJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ\nCQ\n", Origin: " kJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ\n CQ\n", }, }, }, { YAML: ` b: 2 a: 1 d: 4 c: 3 sub: e: 5 `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "b", Origin: "\nb", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "2", Origin: " 2\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1", Origin: " 1\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "d", Origin: "d", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "4", Origin: " 4\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "c", Origin: "c", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "3", Origin: " 3\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "sub", Origin: "sub", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "e", Origin: "\n e", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.IntegerType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "5", Origin: " 5", }, }, }, { YAML: `a: 1.2.3.4`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1.2.3.4", Origin: " 1.2.3.4", }, }, }, { YAML: `a: "2015-02-24T18:19:39Z"`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "2015-02-24T18:19:39Z", Origin: " \"2015-02-24T18:19:39Z\"", }, }, }, { YAML: `a: 'b: c'`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SingleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "b: c", Origin: " 'b: c'", }, }, }, { YAML: `a: 'Hello #comment'`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SingleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "Hello #comment", Origin: " 'Hello #comment'", }, }, }, { YAML: `a: 100.5`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FloatType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "100.5", Origin: " 100.5", }, }, }, { YAML: `a: bogus`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "a", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "bogus", Origin: " bogus", }, }, }, { YAML: `"a": double quoted map key`, Tokens: token.Tokens{ { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "a", Origin: "\"a\"", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "double quoted map key", Origin: " double quoted map key", }, }, }, { YAML: `'a': single quoted map key`, Tokens: token.Tokens{ { Type: token.SingleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "a", Origin: "'a'", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "single quoted map key", Origin: " single quoted map key", }, }, }, { YAML: ` a: "double quoted" b: "value map"`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "double quoted", Origin: " \"double quoted\"", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "b", Origin: "\nb", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "value map", Origin: " \"value map\"", }, }, }, { YAML: ` a: 'single quoted' b: 'value map'`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SingleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "single quoted", Origin: " 'single quoted'", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "b", Origin: "\nb", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SingleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "value map", Origin: " 'value map'", }, }, }, { YAML: `json: '\"expression\": \"thi:\"'`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "json", Origin: "json", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.SingleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "\\\"expression\\\": \\\"thi:\\\"", Origin: " '\\\"expression\\\": \\\"thi:\\\"'", }, }, }, { YAML: `json: "\"expression\": \"thi:\""`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "json", Origin: "json", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.DoubleQuoteType, CharacterType: token.CharacterTypeIndicator, Indicator: token.QuotedScalarIndicator, Value: "\"expression\": \"thi:\"", Origin: " \"\\\"expression\\\": \\\"thi:\\\"\"", }, }, }, { YAML: ` a: b c `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "b\nc", Origin: "\n b\n\n c", }, }, }, { YAML: ` a: b c d e: f `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "b\nc d", Origin: "\n b\n\n\n c\n d\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "e", Origin: "e", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "f", Origin: " f", }, }, }, { YAML: ` a: | b c d e: f `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.LiteralType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: "|", Origin: " |\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "b \n\n \nc\nd \n", Origin: " b \n\n \n c\n d \n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "e", Origin: "e", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "f", Origin: " f", }, }, }, { YAML: ` a: > b c d e: f `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">", Origin: " >\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "b \n\n \nc d \n", Origin: " b \n\n \n c\n d \n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "e", Origin: "e", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "f", Origin: " f", }, }, }, { YAML: ` a: > Text`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a", Origin: "\na", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">", Origin: " >\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "Text", Origin: " Text", }, }, }, { YAML: ` s: > 1s `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "s", Origin: "\ns", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">", Origin: " >\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1s\n", Origin: " 1s\n", }, }, }, { YAML: ` s: >1 # comment 1s `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "s", Origin: "\ns", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">1", Origin: " >1 ", }, { Type: token.CommentType, CharacterType: token.CharacterTypeIndicator, Indicator: token.CommentIndicator, Value: " comment", Origin: "# comment\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: " 1s\n", Origin: " 1s\n", }, }, }, { YAML: ` s: >+2 1s `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "s", Origin: "\ns", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">+2", Origin: " >+2\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: " 1s\n", Origin: " 1s\n", }, }, }, { YAML: ` s: >-3 1s `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "s", Origin: "\ns", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">-3", Origin: " >-3\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: " 1s", Origin: " 1s\n", }, }, }, { YAML: ` s: > 1s 2s `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "s", Origin: "\ns", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">", Origin: " >\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1s 2s\n", Origin: " 1s\n 2s\n", }, }, }, { YAML: ` s: > 1s 2s 3s `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "s", Origin: "\ns", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">", Origin: " >\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1s\n 2s\n3s\n", Origin: " 1s\n 2s\n 3s\n", }, }, }, { YAML: ` s: > 1s 2s 3s 4s 5s `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "s", Origin: "\ns", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">", Origin: " >\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1s\n 2s\n 3s\n4s 5s\n", Origin: " 1s\n 2s\n 3s\n 4s\n 5s\n", }, }, }, { YAML: ` s: >-3 1s 2s 3s 4s 5s `, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "s", Origin: "\ns", }, { Type: token.MappingValueType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockStructureIndicator, Value: ":", Origin: ":", }, { Type: token.FoldedType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: ">-3", Origin: " >-3\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: " 1s\n 2s\n 3s\n 4s\n 5s", Origin: " 1s\n 2s\n 3s\n 4s\n 5s\n", }, }, }, { YAML: ` |2- text `, Tokens: token.Tokens{ { Type: token.LiteralType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: "|2-", Origin: "\n|2-\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "\n text", Origin: "\n text\n", }, }, }, { YAML: ` | a `, Tokens: token.Tokens{ { Type: token.LiteralType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: "|", Origin: "\n|\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "a\n", Origin: " a\n\n\n\n", }, }, }, { YAML: ` | # comment foo `, Tokens: token.Tokens{ { Type: token.LiteralType, CharacterType: token.CharacterTypeIndicator, Indicator: token.BlockScalarIndicator, Value: "|", Origin: "\n| ", }, { Type: token.CommentType, CharacterType: token.CharacterTypeIndicator, Indicator: token.CommentIndicator, Value: " comment", Origin: "# comment\n", }, { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "foo\n", Origin: " foo\n", }, }, }, { YAML: `1x0`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "1x0", Origin: "1x0", }, }, }, { YAML: `0b98765`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "0b98765", Origin: "0b98765", }, }, }, { YAML: `098765`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "098765", Origin: "098765", }, }, }, { YAML: `0o98765`, Tokens: token.Tokens{ { Type: token.StringType, CharacterType: token.CharacterTypeMiscellaneous, Indicator: token.NotIndicator, Value: "0o98765", Origin: "0o98765", }, }, }, } for _, test := range tests { t.Run(test.YAML, func(t *testing.T) { tokens := lexer.Tokenize(test.YAML) if len(tokens) != len(test.Tokens) { t.Fatalf("Tokenize(%q) token count mismatch, expected: %d got: %d", test.YAML, len(test.Tokens), len(tokens)) } for i := range test.Tokens { if tokens[i].Type != test.Tokens[i].Type { t.Errorf("Tokenize(%q)[%d] token.Type mismatch, expected: %s got: %s", test.YAML, i, test.Tokens[i].Type, tokens[i].Type) } if tokens[i].CharacterType != test.Tokens[i].CharacterType { t.Errorf("Tokenize(%q)[%d] token.CharacterType mismatch, expected: %s got: %s", test.YAML, i, test.Tokens[i].CharacterType, tokens[i].CharacterType) } if tokens[i].Indicator != test.Tokens[i].Indicator { t.Errorf("Tokenize(%q)[%d] token.Indicator mismatch, expected: %s got: %s", test.YAML, i, test.Tokens[i].Indicator, tokens[i].Indicator) } if tokens[i].Value != test.Tokens[i].Value { t.Errorf("Tokenize(%q)[%d] token.Value mismatch, expected: %q got: %q", test.YAML, i, test.Tokens[i].Value, tokens[i].Value) } if tokens[i].Origin != test.Tokens[i].Origin { t.Errorf("Tokenize(%q)[%d] token.Origin mismatch, expected: %q got: %q", test.YAML, i, test.Tokens[i].Origin, tokens[i].Origin) } } }) } } type testToken struct { line int column int value string } func TestSingleLineToken_ValueLineColumnPosition(t *testing.T) { tests := []struct { name string src string expect map[int]string // Column -> Value map. }{ { name: "single quote, single value array", src: "test: ['test']", expect: map[int]string{ 1: "test", 5: ":", 7: "[", 8: "test", 14: "]", }, }, { name: "double quote, single value array", src: `test: ["test"]`, expect: map[int]string{ 1: "test", 5: ":", 7: "[", 8: "test", 14: "]", }, }, { name: "no quotes, single value array", src: "test: [somevalue]", expect: map[int]string{ 1: "test", 5: ":", 7: "[", 8: "somevalue", 17: "]", }, }, { name: "single quote, multi value array", src: "myarr: ['1','2','3', '444' , '55','66' , '77' ]", expect: map[int]string{ 1: "myarr", 6: ":", 8: "[", 9: "1", 12: ",", 13: "2", 16: ",", 17: "3", 20: ",", 22: "444", 28: ",", 30: "55", 34: ",", 35: "66", 40: ",", 43: "77", 49: "]", }, }, { name: "double quote, multi value array", src: `myarr: ["1","2","3", "444" , "55","66" , "77" ]`, expect: map[int]string{ 1: "myarr", 6: ":", 8: "[", 9: "1", 12: ",", 13: "2", 16: ",", 17: "3", 20: ",", 22: "444", 28: ",", 30: "55", 34: ",", 35: "66", 40: ",", 43: "77", 49: "]", }, }, { name: "no quote, multi value array", src: "numbers: [1, 5, 99,100, 3, 7 ]", expect: map[int]string{ 1: "numbers", 8: ":", 10: "[", 11: "1", 12: ",", 14: "5", 15: ",", 17: "99", 19: ",", 20: "100", 23: ",", 25: "3", 26: ",", 28: "7", 30: "]", }, }, { name: "double quotes, nested arrays", src: `Strings: ["1",["2",["3"]]]`, expect: map[int]string{ 1: "Strings", 8: ":", 10: "[", 11: "1", 14: ",", 15: "[", 16: "2", 19: ",", 20: "[", 21: "3", 24: "]", 25: "]", 26: "]", }, }, { name: "mixed quotes, nested arrays", src: `Values: [1,['2',"3",4,["5",6]]]`, expect: map[int]string{ 1: "Values", 7: ":", 9: "[", 10: "1", 11: ",", 12: "[", 13: "2", 16: ",", 17: "3", 20: ",", 21: "4", 22: ",", 23: "[", 24: "5", 27: ",", 28: "6", 29: "]", 30: "]", 31: "]", }, }, { name: "double quote, empty array", src: `Empty: ["", ""]`, expect: map[int]string{ 1: "Empty", 6: ":", 8: "[", 9: "", 11: ",", 13: "", 15: "]", }, }, { name: "double quote key", src: `"a": b`, expect: map[int]string{ 1: "a", 4: ":", 6: "b", }, }, { name: "single quote key", src: `'a': b`, expect: map[int]string{ 1: "a", 4: ":", 6: "b", }, }, { name: "double quote key and value", src: `"a": "b"`, expect: map[int]string{ 1: "a", 4: ":", 6: "b", }, }, { name: "single quote key and value", src: `'a': 'b'`, expect: map[int]string{ 1: "a", 4: ":", 6: "b", }, }, { name: "double quote key, single quote value", src: `"a": 'b'`, expect: map[int]string{ 1: "a", 4: ":", 6: "b", }, }, { name: "single quote key, double quote value", src: `'a': "b"`, expect: map[int]string{ 1: "a", 4: ":", 6: "b", }, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { got := lexer.Tokenize(tc.src) sort.Slice(got, func(i, j int) bool { return got[i].Position.Column < got[j].Position.Column }) var expected []testToken for k, v := range tc.expect { tt := testToken{ line: 1, column: k, value: v, } expected = append(expected, tt) } sort.Slice(expected, func(i, j int) bool { return expected[i].column < expected[j].column }) if len(got) != len(expected) { t.Errorf("Tokenize(%s) token count mismatch, expected:%d got:%d", tc.src, len(expected), len(got)) } for i, tok := range got { if !tokenMatches(tok, expected[i]) { t.Errorf("Tokenize(%s) expected:%+v got line:%d column:%d value:%s", tc.src, expected[i], tok.Position.Line, tok.Position.Column, tok.Value) } } }) } } func tokenMatches(t *token.Token, e testToken) bool { return t != nil && t.Position != nil && t.Value == e.value && t.Position.Line == e.line && t.Position.Column == e.column } func TestMultiLineToken_ValueLineColumnPosition(t *testing.T) { tests := []struct { name string src string expect []testToken }{ { name: "double quote", src: `one: "1 2 3 4 5" two: "1 2 3 4 5" three: "1 2 3 4 5"`, expect: []testToken{ { line: 1, column: 1, value: "one", }, { line: 1, column: 4, value: ":", }, { line: 1, column: 6, value: "1 2 3 4 5", }, { line: 2, column: 1, value: "two", }, { line: 2, column: 4, value: ":", }, { line: 2, column: 6, value: "1 2 3 4 5", }, { line: 5, column: 1, value: "three", }, { line: 5, column: 6, value: ":", }, { line: 5, column: 8, value: "1 2 3 4 5", }, }, }, { name: "single quote in an array", src: `arr: ['1', 'and two'] last: 'hello'`, expect: []testToken{ { line: 1, column: 1, value: "arr", }, { line: 1, column: 4, value: ":", }, { line: 1, column: 6, value: "[", }, { line: 1, column: 7, value: "1", }, { line: 1, column: 10, value: ",", }, { line: 1, column: 12, value: "and two", }, { line: 2, column: 5, value: "]", }, { line: 3, column: 1, value: "last", }, { line: 3, column: 5, value: ":", }, { line: 3, column: 7, value: "hello", }, }, }, { name: "single quote and double quote", src: `foo: "test bar" foo2: 'bar2'`, expect: []testToken{ { line: 1, column: 1, value: "foo", }, { line: 1, column: 4, value: ":", }, { line: 1, column: 6, value: "test\n\n\n\nbar", }, { line: 7, column: 1, value: "foo2", }, { line: 7, column: 5, value: ":", }, { line: 7, column: 7, value: "bar2", }, }, }, { name: "single and double quote map keys", src: `"a": test 'b': 1 c: true`, expect: []testToken{ { line: 1, column: 1, value: "a", }, { line: 1, column: 4, value: ":", }, { line: 1, column: 6, value: "test", }, { line: 2, column: 1, value: "b", }, { line: 2, column: 4, value: ":", }, { line: 2, column: 6, value: "1", }, { line: 3, column: 1, value: "c", }, { line: 3, column: 2, value: ":", }, { line: 3, column: 4, value: "true", }, }, }, { name: "issue326", src: `a: | Text b: 1`, expect: []testToken{ { line: 1, column: 1, value: "a", }, { line: 1, column: 2, value: ":", }, { line: 1, column: 4, value: "|", }, { line: 2, column: 3, value: "Text\n", }, { line: 3, column: 1, value: "b", }, { line: 3, column: 2, value: ":", }, { line: 3, column: 4, value: "1", }, }, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { got := lexer.Tokenize(tc.src) sort.Slice(got, func(i, j int) bool { // sort by line, then column if got[i].Position.Line < got[j].Position.Line { return true } else if got[i].Position.Line == got[j].Position.Line { return got[i].Position.Column < got[j].Position.Column } return false }) sort.Slice(tc.expect, func(i, j int) bool { if tc.expect[i].line < tc.expect[j].line { return true } else if tc.expect[i].line == tc.expect[j].line { return tc.expect[i].column < tc.expect[j].column } return false }) if len(got) != len(tc.expect) { t.Errorf("Tokenize() token count mismatch, expected:%d got:%d", len(tc.expect), len(got)) } for i, tok := range got { if !tokenMatches(tok, tc.expect[i]) { t.Errorf("Tokenize() expected:%+v got line:%d column:%d value:%s", tc.expect[i], tok.Position.Line, tok.Position.Column, tok.Value) } } }) } } func TestInvalid(t *testing.T) { tests := []struct { name string src string }{ { name: "literal opt with content", src: ` a: |invalid foo`, }, { name: "literal opt", src: ` a: |invalid`, }, { name: "invalid single-quoted", src: `a: 'foobarbaz`, }, { name: "invalid double-quoted", src: `a: "\"key\": \"value:\"`, }, { name: "invalid document folded", src: ">\n>", }, { name: "invalid document number", src: ">\n1", }, { name: "invalid document header option number", src: "a: >3\n 1", }, { name: "use reserved character @", src: "key: [@val]", }, { name: "use reserved character `", src: "key: [`val]", }, { name: "use tab character as indent", // nolint: gci src: " a: b", }, { name: "use tab character as indent in literal", src: ` a: | b c `, }, { name: "invalid UTF-16 character", src: `"\u00"`, }, { name: "invalid UTF-16 surrogate pair length", src: `"\ud800"`, }, { name: "invalid UTF-16 low surrogate prefix", src: `"\ud800\v"`, }, { name: "invalid UTF-16 low surrogate", src: `"\ud800\u0000"`, }, { name: "invalid UTF-32 character", src: `"\U0000"`, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { got := lexer.Tokenize(test.src) if got.InvalidToken() == nil { t.Fatal("expected contains invalid token") } }) } } func TestTokenOffset(t *testing.T) { t.Run("crlf", func(t *testing.T) { content := "project:\r\n version: 1.2.3\r\n" tokens := lexer.Tokenize(content) if len(tokens) != 5 { t.Fatalf("invalid token num. got %d", len(tokens)) } if tokens[4].Value != "1.2.3" { t.Fatalf("unexpected value. got %q", tokens[4].Value) } if tokens[4].Position.Offset != 22 { t.Fatalf("unexpected offset. got %d", tokens[4].Position.Offset) } }) t.Run("lf", func(t *testing.T) { content := "project:\n version: 1.2.3\n" tokens := lexer.Tokenize(content) if len(tokens) != 5 { t.Fatalf("invalid token num. got %d", len(tokens)) } if tokens[4].Value != "1.2.3" { t.Fatalf("unexpected value. got %q", tokens[4].Value) } if tokens[4].Position.Offset != 21 { t.Fatalf("unexpected offset. got %d", tokens[4].Position.Offset) } }) } goccy-go-yaml-52dacb8/option.go000066400000000000000000000232451501576637100165330ustar00rootroot00000000000000package yaml import ( "context" "io" "reflect" "github.com/goccy/go-yaml/ast" ) // DecodeOption functional option type for Decoder type DecodeOption func(d *Decoder) error // ReferenceReaders pass to Decoder that reference to anchor defined by passed readers func ReferenceReaders(readers ...io.Reader) DecodeOption { return func(d *Decoder) error { d.referenceReaders = append(d.referenceReaders, readers...) return nil } } // ReferenceFiles pass to Decoder that reference to anchor defined by passed files func ReferenceFiles(files ...string) DecodeOption { return func(d *Decoder) error { d.referenceFiles = files return nil } } // ReferenceDirs pass to Decoder that reference to anchor defined by files under the passed dirs func ReferenceDirs(dirs ...string) DecodeOption { return func(d *Decoder) error { d.referenceDirs = dirs return nil } } // RecursiveDir search yaml file recursively from passed dirs by ReferenceDirs option func RecursiveDir(isRecursive bool) DecodeOption { return func(d *Decoder) error { d.isRecursiveDir = isRecursive return nil } } // Validator set StructValidator instance to Decoder func Validator(v StructValidator) DecodeOption { return func(d *Decoder) error { d.validator = v return nil } } // Strict enable DisallowUnknownField func Strict() DecodeOption { return func(d *Decoder) error { d.disallowUnknownField = true return nil } } // DisallowUnknownField causes the Decoder to return an error when the destination // is a struct and the input contains object keys which do not match any // non-ignored, exported fields in the destination. func DisallowUnknownField() DecodeOption { return func(d *Decoder) error { d.disallowUnknownField = true return nil } } // AllowDuplicateMapKey ignore syntax error when mapping keys that are duplicates. func AllowDuplicateMapKey() DecodeOption { return func(d *Decoder) error { d.allowDuplicateMapKey = true return nil } } // UseOrderedMap can be interpreted as a map, // and uses MapSlice ( ordered map ) aggressively if there is no type specification func UseOrderedMap() DecodeOption { return func(d *Decoder) error { d.useOrderedMap = true return nil } } // UseJSONUnmarshaler if neither `BytesUnmarshaler` nor `InterfaceUnmarshaler` is implemented // and `UnmashalJSON([]byte)error` is implemented, convert the argument from `YAML` to `JSON` and then call it. func UseJSONUnmarshaler() DecodeOption { return func(d *Decoder) error { d.useJSONUnmarshaler = true return nil } } // CustomUnmarshaler overrides any decoding process for the type specified in generics. // // NOTE: If RegisterCustomUnmarshaler and CustomUnmarshaler of DecodeOption are specified for the same type, // the CustomUnmarshaler specified in DecodeOption takes precedence. func CustomUnmarshaler[T any](unmarshaler func(*T, []byte) error) DecodeOption { return func(d *Decoder) error { var typ *T d.customUnmarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}, b []byte) error { return unmarshaler(v.(*T), b) } return nil } } // CustomUnmarshalerContext overrides any decoding process for the type specified in generics. // Similar to CustomUnmarshaler, but allows passing a context to the unmarshaler function. func CustomUnmarshalerContext[T any](unmarshaler func(context.Context, *T, []byte) error) DecodeOption { return func(d *Decoder) error { var typ *T d.customUnmarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}, b []byte) error { return unmarshaler(ctx, v.(*T), b) } return nil } } // EncodeOption functional option type for Encoder type EncodeOption func(e *Encoder) error // Indent change indent number func Indent(spaces int) EncodeOption { return func(e *Encoder) error { e.indentNum = spaces return nil } } // IndentSequence causes sequence values to be indented the same value as Indent func IndentSequence(indent bool) EncodeOption { return func(e *Encoder) error { e.indentSequence = indent return nil } } // UseSingleQuote determines if single or double quotes should be preferred for strings. func UseSingleQuote(sq bool) EncodeOption { return func(e *Encoder) error { e.singleQuote = sq return nil } } // Flow encoding by flow style func Flow(isFlowStyle bool) EncodeOption { return func(e *Encoder) error { e.isFlowStyle = isFlowStyle return nil } } // WithSmartAnchor when multiple map values share the same pointer, // an anchor is automatically assigned to the first occurrence, and aliases are used for subsequent elements. // The map key name is used as the anchor name by default. // If key names conflict, a suffix is automatically added to avoid collisions. // This is an experimental feature and cannot be used simultaneously with anchor tags. func WithSmartAnchor() EncodeOption { return func(e *Encoder) error { e.enableSmartAnchor = true return nil } } // UseLiteralStyleIfMultiline causes encoding multiline strings with a literal syntax, // no matter what characters they include func UseLiteralStyleIfMultiline(useLiteralStyleIfMultiline bool) EncodeOption { return func(e *Encoder) error { e.useLiteralStyleIfMultiline = useLiteralStyleIfMultiline return nil } } // JSON encode in JSON format func JSON() EncodeOption { return func(e *Encoder) error { e.isJSONStyle = true e.isFlowStyle = true return nil } } // MarshalAnchor call back if encoder find an anchor during encoding func MarshalAnchor(callback func(*ast.AnchorNode, interface{}) error) EncodeOption { return func(e *Encoder) error { e.anchorCallback = callback return nil } } // UseJSONMarshaler if neither `BytesMarshaler` nor `InterfaceMarshaler` // nor `encoding.TextMarshaler` is implemented and `MarshalJSON()([]byte, error)` is implemented, // call `MarshalJSON` to convert the returned `JSON` to `YAML` for processing. func UseJSONMarshaler() EncodeOption { return func(e *Encoder) error { e.useJSONMarshaler = true return nil } } // CustomMarshaler overrides any encoding process for the type specified in generics. // // NOTE: If type T implements MarshalYAML for pointer receiver, the type specified in CustomMarshaler must be *T. // If RegisterCustomMarshaler and CustomMarshaler of EncodeOption are specified for the same type, // the CustomMarshaler specified in EncodeOption takes precedence. func CustomMarshaler[T any](marshaler func(T) ([]byte, error)) EncodeOption { return func(e *Encoder) error { var typ T e.customMarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}) ([]byte, error) { return marshaler(v.(T)) } return nil } } // CustomMarshalerContext overrides any encoding process for the type specified in generics. // Similar to CustomMarshaler, but allows passing a context to the marshaler function. func CustomMarshalerContext[T any](marshaler func(context.Context, T) ([]byte, error)) EncodeOption { return func(e *Encoder) error { var typ T e.customMarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}) ([]byte, error) { return marshaler(ctx, v.(T)) } return nil } } // AutoInt automatically converts floating-point numbers to integers when the fractional part is zero. // For example, a value of 1.0 will be encoded as 1. func AutoInt() EncodeOption { return func(e *Encoder) error { e.autoInt = true return nil } } // OmitEmpty behaves in the same way as the interpretation of the omitempty tag in the encoding/json library. // set on all the fields. // In the current implementation, the omitempty tag is not implemented in the same way as encoding/json, // so please specify this option if you expect the same behavior. func OmitEmpty() EncodeOption { return func(e *Encoder) error { e.omitEmpty = true return nil } } // OmitZero forces the encoder to assume an `omitzero` struct tag is // set on all the fields. See `Marshal` commentary for the `omitzero` tag logic. func OmitZero() EncodeOption { return func(e *Encoder) error { e.omitZero = true return nil } } // CommentPosition type of the position for comment. type CommentPosition int const ( CommentHeadPosition CommentPosition = CommentPosition(iota) CommentLinePosition CommentFootPosition ) func (p CommentPosition) String() string { switch p { case CommentHeadPosition: return "Head" case CommentLinePosition: return "Line" case CommentFootPosition: return "Foot" default: return "" } } // LineComment create a one-line comment for CommentMap. func LineComment(text string) *Comment { return &Comment{ Texts: []string{text}, Position: CommentLinePosition, } } // HeadComment create a multiline comment for CommentMap. func HeadComment(texts ...string) *Comment { return &Comment{ Texts: texts, Position: CommentHeadPosition, } } // FootComment create a multiline comment for CommentMap. func FootComment(texts ...string) *Comment { return &Comment{ Texts: texts, Position: CommentFootPosition, } } // Comment raw data for comment. type Comment struct { Texts []string Position CommentPosition } // CommentMap map of the position of the comment and the comment information. type CommentMap map[string][]*Comment // WithComment add a comment using the location and text information given in the CommentMap. func WithComment(cm CommentMap) EncodeOption { return func(e *Encoder) error { commentMap := map[*Path][]*Comment{} for k, v := range cm { path, err := PathString(k) if err != nil { return err } commentMap[path] = v } e.commentMap = commentMap return nil } } // CommentToMap apply the position and content of comments in a YAML document to a CommentMap. func CommentToMap(cm CommentMap) DecodeOption { return func(d *Decoder) error { if cm == nil { return ErrInvalidCommentMapValue } d.toCommentMap = cm return nil } } goccy-go-yaml-52dacb8/parser/000077500000000000000000000000001501576637100161625ustar00rootroot00000000000000goccy-go-yaml-52dacb8/parser/color.go000066400000000000000000000007361501576637100176350ustar00rootroot00000000000000package parser import "fmt" const ( colorFgHiBlack int = iota + 90 colorFgHiRed colorFgHiGreen colorFgHiYellow colorFgHiBlue colorFgHiMagenta colorFgHiCyan ) var colorTable = []int{ colorFgHiRed, colorFgHiGreen, colorFgHiYellow, colorFgHiBlue, colorFgHiMagenta, colorFgHiCyan, } func colorize(idx int, content string) string { colorIdx := idx % len(colorTable) color := colorTable[colorIdx] return fmt.Sprintf("\x1b[1;%dm", color) + content + "\x1b[22;0m" } goccy-go-yaml-52dacb8/parser/context.go000066400000000000000000000067511501576637100202060ustar00rootroot00000000000000package parser import ( "fmt" "strings" "github.com/goccy/go-yaml/token" ) // context context at parsing type context struct { tokenRef *tokenRef path string isFlow bool } type tokenRef struct { tokens []*Token size int idx int } var pathSpecialChars = []string{ "$", "*", ".", "[", "]", } func containsPathSpecialChar(path string) bool { for _, char := range pathSpecialChars { if strings.Contains(path, char) { return true } } return false } func normalizePath(path string) string { if containsPathSpecialChar(path) { return fmt.Sprintf("'%s'", path) } return path } func (c *context) currentToken() *Token { if c.tokenRef.idx >= c.tokenRef.size { return nil } return c.tokenRef.tokens[c.tokenRef.idx] } func (c *context) isComment() bool { return c.currentToken().Type() == token.CommentType } func (c *context) nextToken() *Token { if c.tokenRef.idx+1 >= c.tokenRef.size { return nil } return c.tokenRef.tokens[c.tokenRef.idx+1] } func (c *context) nextNotCommentToken() *Token { for i := c.tokenRef.idx + 1; i < c.tokenRef.size; i++ { tk := c.tokenRef.tokens[i] if tk.Type() == token.CommentType { continue } return tk } return nil } func (c *context) isTokenNotFound() bool { return c.currentToken() == nil } func (c *context) withGroup(g *TokenGroup) *context { ctx := *c ctx.tokenRef = &tokenRef{ tokens: g.Tokens, size: len(g.Tokens), } return &ctx } func (c *context) withChild(path string) *context { ctx := *c ctx.path = c.path + "." + normalizePath(path) return &ctx } func (c *context) withIndex(idx uint) *context { ctx := *c ctx.path = c.path + "[" + fmt.Sprint(idx) + "]" return &ctx } func (c *context) withFlow(isFlow bool) *context { ctx := *c ctx.isFlow = isFlow return &ctx } func newContext() *context { return &context{ path: "$", } } func (c *context) goNext() { ref := c.tokenRef if ref.size <= ref.idx+1 { ref.idx = ref.size } else { ref.idx++ } } func (c *context) next() bool { return c.tokenRef.idx < c.tokenRef.size } func (c *context) insertNullToken(tk *Token) *Token { nullToken := c.createImplicitNullToken(tk) c.insertToken(nullToken) c.goNext() return nullToken } func (c *context) addNullValueToken(tk *Token) *Token { nullToken := c.createImplicitNullToken(tk) rawTk := nullToken.RawToken() // add space for map or sequence value. rawTk.Position.Column++ c.addToken(nullToken) c.goNext() return nullToken } func (c *context) createImplicitNullToken(base *Token) *Token { pos := *(base.RawToken().Position) pos.Column++ tk := token.New("null", " null", &pos) tk.Type = token.ImplicitNullType return &Token{Token: tk} } func (c *context) insertToken(tk *Token) { ref := c.tokenRef idx := ref.idx if ref.size < idx { return } if ref.size == idx { curToken := ref.tokens[ref.size-1] tk.RawToken().Next = curToken.RawToken() curToken.RawToken().Prev = tk.RawToken() ref.tokens = append(ref.tokens, tk) ref.size = len(ref.tokens) return } curToken := ref.tokens[idx] tk.RawToken().Next = curToken.RawToken() curToken.RawToken().Prev = tk.RawToken() ref.tokens = append(ref.tokens[:idx+1], ref.tokens[idx:]...) ref.tokens[idx] = tk ref.size = len(ref.tokens) } func (c *context) addToken(tk *Token) { ref := c.tokenRef lastTk := ref.tokens[ref.size-1] if lastTk.Group != nil { lastTk = lastTk.Group.Last() } lastTk.RawToken().Next = tk.RawToken() tk.RawToken().Prev = lastTk.RawToken() ref.tokens = append(ref.tokens, tk) ref.size = len(ref.tokens) } goccy-go-yaml-52dacb8/parser/node.go000066400000000000000000000147551501576637100174520ustar00rootroot00000000000000package parser import ( "fmt" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" "github.com/goccy/go-yaml/token" ) func newMappingNode(ctx *context, tk *Token, isFlow bool, values ...*ast.MappingValueNode) (*ast.MappingNode, error) { node := ast.Mapping(tk.RawToken(), isFlow, values...) node.SetPath(ctx.path) return node, nil } func newMappingValueNode(ctx *context, colonTk, entryTk *Token, key ast.MapKeyNode, value ast.Node) (*ast.MappingValueNode, error) { node := ast.MappingValue(colonTk.RawToken(), key, value) node.SetPath(ctx.path) node.CollectEntry = entryTk.RawToken() if key.GetToken().Position.Line == value.GetToken().Position.Line { // originally key was commented, but now that null value has been added, value must be commented. if err := setLineComment(ctx, value, colonTk); err != nil { return nil, err } // set line comment by colonTk or entryTk. if err := setLineComment(ctx, value, entryTk); err != nil { return nil, err } } else { if err := setLineComment(ctx, key, colonTk); err != nil { return nil, err } // set line comment by colonTk or entryTk. if err := setLineComment(ctx, key, entryTk); err != nil { return nil, err } } return node, nil } func newMappingKeyNode(ctx *context, tk *Token) (*ast.MappingKeyNode, error) { node := ast.MappingKey(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newAnchorNode(ctx *context, tk *Token) (*ast.AnchorNode, error) { node := ast.Anchor(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newAliasNode(ctx *context, tk *Token) (*ast.AliasNode, error) { node := ast.Alias(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newDirectiveNode(ctx *context, tk *Token) (*ast.DirectiveNode, error) { node := ast.Directive(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newMergeKeyNode(ctx *context, tk *Token) (*ast.MergeKeyNode, error) { node := ast.MergeKey(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newNullNode(ctx *context, tk *Token) (*ast.NullNode, error) { node := ast.Null(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newBoolNode(ctx *context, tk *Token) (*ast.BoolNode, error) { node := ast.Bool(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newIntegerNode(ctx *context, tk *Token) (*ast.IntegerNode, error) { node := ast.Integer(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newFloatNode(ctx *context, tk *Token) (*ast.FloatNode, error) { node := ast.Float(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newInfinityNode(ctx *context, tk *Token) (*ast.InfinityNode, error) { node := ast.Infinity(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newNanNode(ctx *context, tk *Token) (*ast.NanNode, error) { node := ast.Nan(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newStringNode(ctx *context, tk *Token) (*ast.StringNode, error) { node := ast.String(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newLiteralNode(ctx *context, tk *Token) (*ast.LiteralNode, error) { node := ast.Literal(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newTagNode(ctx *context, tk *Token) (*ast.TagNode, error) { node := ast.Tag(tk.RawToken()) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newSequenceNode(ctx *context, tk *Token, isFlow bool) (*ast.SequenceNode, error) { node := ast.Sequence(tk.RawToken(), isFlow) node.SetPath(ctx.path) if err := setLineComment(ctx, node, tk); err != nil { return nil, err } return node, nil } func newTagDefaultScalarValueNode(ctx *context, tag *token.Token) (ast.ScalarNode, error) { pos := *(tag.Position) pos.Column++ var ( tk *Token node ast.ScalarNode ) switch token.ReservedTagKeyword(tag.Value) { case token.IntegerTag: tk = &Token{Token: token.New("0", "0", &pos)} n, err := newIntegerNode(ctx, tk) if err != nil { return nil, err } node = n case token.FloatTag: tk = &Token{Token: token.New("0", "0", &pos)} n, err := newFloatNode(ctx, tk) if err != nil { return nil, err } node = n case token.StringTag, token.BinaryTag, token.TimestampTag: tk = &Token{Token: token.New("", "", &pos)} n, err := newStringNode(ctx, tk) if err != nil { return nil, err } node = n case token.BooleanTag: tk = &Token{Token: token.New("false", "false", &pos)} n, err := newBoolNode(ctx, tk) if err != nil { return nil, err } node = n case token.NullTag: tk = &Token{Token: token.New("null", "null", &pos)} n, err := newNullNode(ctx, tk) if err != nil { return nil, err } node = n default: return nil, errors.ErrSyntax(fmt.Sprintf("cannot assign default value for %q tag", tag.Value), tag) } ctx.insertToken(tk) ctx.goNext() return node, nil } func setLineComment(ctx *context, node ast.Node, tk *Token) error { if tk == nil || tk.LineComment == nil { return nil } comment := ast.CommentGroup([]*token.Token{tk.LineComment}) comment.SetPath(ctx.path) if err := node.SetComment(comment); err != nil { return err } return nil } func setHeadComment(cm *ast.CommentGroupNode, value ast.Node) error { if cm == nil { return nil } switch n := value.(type) { case *ast.MappingNode: if len(n.Values) != 0 && value.GetComment() == nil { cm.SetPath(n.Values[0].GetPath()) return n.Values[0].SetComment(cm) } case *ast.MappingValueNode: cm.SetPath(n.GetPath()) return n.SetComment(cm) } cm.SetPath(value.GetPath()) return value.SetComment(cm) } goccy-go-yaml-52dacb8/parser/option.go000066400000000000000000000004631501576637100200240ustar00rootroot00000000000000package parser // Option represents parser's option. type Option func(p *parser) // AllowDuplicateMapKey allow the use of keys with the same name in the same map, // but by default, this is not permitted. func AllowDuplicateMapKey() Option { return func(p *parser) { p.allowDuplicateMapKey = true } } goccy-go-yaml-52dacb8/parser/parser.go000066400000000000000000001054631501576637100200160ustar00rootroot00000000000000package parser import ( "fmt" "os" "strings" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" "github.com/goccy/go-yaml/lexer" "github.com/goccy/go-yaml/token" ) type Mode uint const ( ParseComments Mode = 1 << iota // parse comments and add them to AST ) // ParseBytes parse from byte slice, and returns ast.File func ParseBytes(bytes []byte, mode Mode, opts ...Option) (*ast.File, error) { tokens := lexer.Tokenize(string(bytes)) f, err := Parse(tokens, mode, opts...) if err != nil { return nil, err } return f, nil } // Parse parse from token instances, and returns ast.File func Parse(tokens token.Tokens, mode Mode, opts ...Option) (*ast.File, error) { if tk := tokens.InvalidToken(); tk != nil { return nil, errors.ErrSyntax(tk.Error, tk) } p, err := newParser(tokens, mode, opts) if err != nil { return nil, err } f, err := p.parse(newContext()) if err != nil { return nil, err } return f, nil } // Parse parse from filename, and returns ast.File func ParseFile(filename string, mode Mode, opts ...Option) (*ast.File, error) { file, err := os.ReadFile(filename) if err != nil { return nil, err } f, err := ParseBytes(file, mode, opts...) if err != nil { return nil, err } f.Name = filename return f, nil } type YAMLVersion string const ( YAML10 YAMLVersion = "1.0" YAML11 YAMLVersion = "1.1" YAML12 YAMLVersion = "1.2" YAML13 YAMLVersion = "1.3" ) var yamlVersionMap = map[string]YAMLVersion{ "1.0": YAML10, "1.1": YAML11, "1.2": YAML12, "1.3": YAML13, } type parser struct { tokens []*Token pathMap map[string]ast.Node yamlVersion YAMLVersion allowDuplicateMapKey bool secondaryTagDirective *ast.DirectiveNode } func newParser(tokens token.Tokens, mode Mode, opts []Option) (*parser, error) { filteredTokens := []*token.Token{} if mode&ParseComments != 0 { filteredTokens = tokens } else { for _, tk := range tokens { if tk.Type == token.CommentType { continue } // keep prev/next reference between tokens containing comments // https://github.com/goccy/go-yaml/issues/254 filteredTokens = append(filteredTokens, tk) } } tks, err := CreateGroupedTokens(token.Tokens(filteredTokens)) if err != nil { return nil, err } p := &parser{ tokens: tks, pathMap: make(map[string]ast.Node), } for _, opt := range opts { opt(p) } return p, nil } func (p *parser) parse(ctx *context) (*ast.File, error) { file := &ast.File{Docs: []*ast.DocumentNode{}} for _, token := range p.tokens { doc, err := p.parseDocument(ctx, token.Group) if err != nil { return nil, err } file.Docs = append(file.Docs, doc) } return file, nil } func (p *parser) parseDocument(ctx *context, docGroup *TokenGroup) (*ast.DocumentNode, error) { if len(docGroup.Tokens) == 0 { return ast.Document(docGroup.RawToken(), nil), nil } p.pathMap = make(map[string]ast.Node) var ( tokens = docGroup.Tokens start *token.Token end *token.Token ) if docGroup.First().Type() == token.DocumentHeaderType { start = docGroup.First().RawToken() tokens = tokens[1:] } if docGroup.Last().Type() == token.DocumentEndType { end = docGroup.Last().RawToken() tokens = tokens[:len(tokens)-1] defer func() { // clear yaml version value if DocumentEnd token (...) is specified. p.yamlVersion = "" }() } if len(tokens) == 0 { return ast.Document(docGroup.RawToken(), nil), nil } body, err := p.parseDocumentBody(ctx.withGroup(&TokenGroup{ Type: TokenGroupDocumentBody, Tokens: tokens, })) if err != nil { return nil, err } node := ast.Document(start, body) node.End = end return node, nil } func (p *parser) parseDocumentBody(ctx *context) (ast.Node, error) { node, err := p.parseToken(ctx, ctx.currentToken()) if err != nil { return nil, err } if ctx.next() { return nil, errors.ErrSyntax("value is not allowed in this context", ctx.currentToken().RawToken()) } return node, nil } func (p *parser) parseToken(ctx *context, tk *Token) (ast.Node, error) { switch tk.GroupType() { case TokenGroupMapKey, TokenGroupMapKeyValue: return p.parseMap(ctx) case TokenGroupDirective: node, err := p.parseDirective(ctx.withGroup(tk.Group), tk.Group) if err != nil { return nil, err } ctx.goNext() return node, nil case TokenGroupDirectiveName: node, err := p.parseDirectiveName(ctx.withGroup(tk.Group)) if err != nil { return nil, err } ctx.goNext() return node, nil case TokenGroupAnchor: node, err := p.parseAnchor(ctx.withGroup(tk.Group), tk.Group) if err != nil { return nil, err } ctx.goNext() return node, nil case TokenGroupAnchorName: anchor, err := p.parseAnchorName(ctx.withGroup(tk.Group)) if err != nil { return nil, err } ctx.goNext() if ctx.isTokenNotFound() { return nil, errors.ErrSyntax("could not find anchor value", tk.RawToken()) } value, err := p.parseToken(ctx, ctx.currentToken()) if err != nil { return nil, err } if _, ok := value.(*ast.AnchorNode); ok { return nil, errors.ErrSyntax("anchors cannot be used consecutively", value.GetToken()) } anchor.Value = value return anchor, nil case TokenGroupAlias: node, err := p.parseAlias(ctx.withGroup(tk.Group)) if err != nil { return nil, err } ctx.goNext() return node, nil case TokenGroupLiteral, TokenGroupFolded: node, err := p.parseLiteral(ctx.withGroup(tk.Group)) if err != nil { return nil, err } ctx.goNext() return node, nil case TokenGroupScalarTag: node, err := p.parseTag(ctx.withGroup(tk.Group)) if err != nil { return nil, err } ctx.goNext() return node, nil } switch tk.Type() { case token.CommentType: return p.parseComment(ctx) case token.TagType: return p.parseTag(ctx) case token.MappingStartType: return p.parseFlowMap(ctx.withFlow(true)) case token.SequenceStartType: return p.parseFlowSequence(ctx.withFlow(true)) case token.SequenceEntryType: return p.parseSequence(ctx) case token.SequenceEndType: // SequenceEndType is always validated in parseFlowSequence. // Therefore, if this is found in other cases, it is treated as a syntax error. return nil, errors.ErrSyntax("could not find '[' character corresponding to ']'", tk.RawToken()) case token.MappingEndType: // MappingEndType is always validated in parseFlowMap. // Therefore, if this is found in other cases, it is treated as a syntax error. return nil, errors.ErrSyntax("could not find '{' character corresponding to '}'", tk.RawToken()) case token.MappingValueType: return nil, errors.ErrSyntax("found an invalid key for this map", tk.RawToken()) } node, err := p.parseScalarValue(ctx, tk) if err != nil { return nil, err } ctx.goNext() return node, nil } func (p *parser) parseScalarValue(ctx *context, tk *Token) (ast.ScalarNode, error) { if tk.Group != nil { switch tk.GroupType() { case TokenGroupAnchor: return p.parseAnchor(ctx.withGroup(tk.Group), tk.Group) case TokenGroupAnchorName: anchor, err := p.parseAnchorName(ctx.withGroup(tk.Group)) if err != nil { return nil, err } ctx.goNext() if ctx.isTokenNotFound() { return nil, errors.ErrSyntax("could not find anchor value", tk.RawToken()) } value, err := p.parseToken(ctx, ctx.currentToken()) if err != nil { return nil, err } if _, ok := value.(*ast.AnchorNode); ok { return nil, errors.ErrSyntax("anchors cannot be used consecutively", value.GetToken()) } anchor.Value = value return anchor, nil case TokenGroupAlias: return p.parseAlias(ctx.withGroup(tk.Group)) case TokenGroupLiteral, TokenGroupFolded: return p.parseLiteral(ctx.withGroup(tk.Group)) case TokenGroupScalarTag: return p.parseTag(ctx.withGroup(tk.Group)) default: return nil, errors.ErrSyntax("unexpected scalar value", tk.RawToken()) } } switch tk.Type() { case token.MergeKeyType: return newMergeKeyNode(ctx, tk) case token.NullType, token.ImplicitNullType: return newNullNode(ctx, tk) case token.BoolType: return newBoolNode(ctx, tk) case token.IntegerType, token.BinaryIntegerType, token.OctetIntegerType, token.HexIntegerType: return newIntegerNode(ctx, tk) case token.FloatType: return newFloatNode(ctx, tk) case token.InfinityType: return newInfinityNode(ctx, tk) case token.NanType: return newNanNode(ctx, tk) case token.StringType, token.SingleQuoteType, token.DoubleQuoteType: return newStringNode(ctx, tk) case token.TagType: // this case applies when it is a scalar tag and its value does not exist. // Examples of cases where the value does not exist include cases like `key: !!str,` or `!!str : value`. return p.parseScalarTag(ctx) } return nil, errors.ErrSyntax("unexpected scalar value type", tk.RawToken()) } func (p *parser) parseFlowMap(ctx *context) (*ast.MappingNode, error) { node, err := newMappingNode(ctx, ctx.currentToken(), true) if err != nil { return nil, err } ctx.goNext() // skip MappingStart token isFirst := true for ctx.next() { tk := ctx.currentToken() if tk.Type() == token.MappingEndType { node.End = tk.RawToken() break } var entryTk *Token if tk.Type() == token.CollectEntryType { entryTk = tk ctx.goNext() } else if !isFirst { return nil, errors.ErrSyntax("',' or '}' must be specified", tk.RawToken()) } if tk := ctx.currentToken(); tk.Type() == token.MappingEndType { // this case is here: "{ elem, }". // In this case, ignore the last element and break mapping parsing. node.End = tk.RawToken() break } mapKeyTk := ctx.currentToken() switch mapKeyTk.GroupType() { case TokenGroupMapKeyValue: value, err := p.parseMapKeyValue(ctx.withGroup(mapKeyTk.Group), mapKeyTk.Group, entryTk) if err != nil { return nil, err } node.Values = append(node.Values, value) ctx.goNext() case TokenGroupMapKey: key, err := p.parseMapKey(ctx.withGroup(mapKeyTk.Group), mapKeyTk.Group) if err != nil { return nil, err } ctx := ctx.withChild(p.mapKeyText(key)) colonTk := mapKeyTk.Group.Last() if p.isFlowMapDelim(ctx.nextToken()) { value, err := newNullNode(ctx, ctx.insertNullToken(colonTk)) if err != nil { return nil, err } mapValue, err := newMappingValueNode(ctx, colonTk, entryTk, key, value) if err != nil { return nil, err } node.Values = append(node.Values, mapValue) ctx.goNext() } else { ctx.goNext() if ctx.isTokenNotFound() { return nil, errors.ErrSyntax("could not find map value", colonTk.RawToken()) } value, err := p.parseToken(ctx, ctx.currentToken()) if err != nil { return nil, err } mapValue, err := newMappingValueNode(ctx, colonTk, entryTk, key, value) if err != nil { return nil, err } node.Values = append(node.Values, mapValue) } default: if !p.isFlowMapDelim(ctx.nextToken()) { errTk := mapKeyTk if errTk == nil { errTk = tk } return nil, errors.ErrSyntax("could not find flow map content", errTk.RawToken()) } key, err := p.parseScalarValue(ctx, mapKeyTk) if err != nil { return nil, err } value, err := newNullNode(ctx, ctx.insertNullToken(mapKeyTk)) if err != nil { return nil, err } mapValue, err := newMappingValueNode(ctx, mapKeyTk, entryTk, key, value) if err != nil { return nil, err } node.Values = append(node.Values, mapValue) ctx.goNext() } isFirst = false } if node.End == nil { return nil, errors.ErrSyntax("could not find flow mapping end token '}'", node.Start) } ctx.goNext() // skip mapping end token. return node, nil } func (p *parser) isFlowMapDelim(tk *Token) bool { return tk.Type() == token.MappingEndType || tk.Type() == token.CollectEntryType } func (p *parser) parseMap(ctx *context) (*ast.MappingNode, error) { keyTk := ctx.currentToken() if keyTk.Group == nil { return nil, errors.ErrSyntax("unexpected map key", keyTk.RawToken()) } var keyValueNode *ast.MappingValueNode if keyTk.GroupType() == TokenGroupMapKeyValue { node, err := p.parseMapKeyValue(ctx.withGroup(keyTk.Group), keyTk.Group, nil) if err != nil { return nil, err } keyValueNode = node ctx.goNext() if err := p.validateMapKeyValueNextToken(ctx, keyTk, ctx.currentToken()); err != nil { return nil, err } } else { key, err := p.parseMapKey(ctx.withGroup(keyTk.Group), keyTk.Group) if err != nil { return nil, err } ctx.goNext() valueTk := ctx.currentToken() if keyTk.Line() == valueTk.Line() && valueTk.Type() == token.SequenceEntryType { return nil, errors.ErrSyntax("block sequence entries are not allowed in this context", valueTk.RawToken()) } ctx := ctx.withChild(p.mapKeyText(key)) value, err := p.parseMapValue(ctx, key, keyTk.Group.Last()) if err != nil { return nil, err } node, err := newMappingValueNode(ctx, keyTk.Group.Last(), nil, key, value) if err != nil { return nil, err } keyValueNode = node } mapNode, err := newMappingNode(ctx, &Token{Token: keyValueNode.GetToken()}, false, keyValueNode) if err != nil { return nil, err } var tk *Token if ctx.isComment() { tk = ctx.nextNotCommentToken() } else { tk = ctx.currentToken() } for tk.Column() == keyTk.Column() { typ := tk.Type() if ctx.isFlow && typ == token.SequenceEndType { // [ // key: value // ] <= break } if !p.isMapToken(tk) { return nil, errors.ErrSyntax("non-map value is specified", tk.RawToken()) } cm := p.parseHeadComment(ctx) if typ == token.MappingEndType { // a: { // b: c // } <= ctx.goNext() break } node, err := p.parseMap(ctx) if err != nil { return nil, err } if len(node.Values) != 0 { if err := setHeadComment(cm, node.Values[0]); err != nil { return nil, err } } mapNode.Values = append(mapNode.Values, node.Values...) if node.FootComment != nil { mapNode.Values[len(mapNode.Values)-1].FootComment = node.FootComment } tk = ctx.currentToken() } if ctx.isComment() { if keyTk.Column() <= ctx.currentToken().Column() { // If the comment is in the same or deeper column as the last element column in map value, // treat it as a footer comment for the last element. if len(mapNode.Values) == 1 { mapNode.Values[0].FootComment = p.parseFootComment(ctx, keyTk.Column()) mapNode.Values[0].FootComment.SetPath(mapNode.Values[0].Key.GetPath()) } else { mapNode.FootComment = p.parseFootComment(ctx, keyTk.Column()) mapNode.FootComment.SetPath(mapNode.GetPath()) } } } return mapNode, nil } func (p *parser) validateMapKeyValueNextToken(ctx *context, keyTk, tk *Token) error { if tk == nil { return nil } if tk.Column() <= keyTk.Column() { return nil } if ctx.isComment() { return nil } if ctx.isFlow && (tk.Type() == token.CollectEntryType || tk.Type() == token.SequenceEndType) { return nil } // a: b // c <= this token is invalid. return errors.ErrSyntax("value is not allowed in this context. map key-value is pre-defined", tk.RawToken()) } func (p *parser) isMapToken(tk *Token) bool { if tk.Group == nil { return tk.Type() == token.MappingStartType || tk.Type() == token.MappingEndType } g := tk.Group return g.Type == TokenGroupMapKey || g.Type == TokenGroupMapKeyValue } func (p *parser) parseMapKeyValue(ctx *context, g *TokenGroup, entryTk *Token) (*ast.MappingValueNode, error) { if g.Type != TokenGroupMapKeyValue { return nil, errors.ErrSyntax("unexpected map key-value pair", g.RawToken()) } if g.First().Group == nil { return nil, errors.ErrSyntax("unexpected map key", g.RawToken()) } keyGroup := g.First().Group key, err := p.parseMapKey(ctx.withGroup(keyGroup), keyGroup) if err != nil { return nil, err } c := ctx.withChild(p.mapKeyText(key)) value, err := p.parseToken(c, g.Last()) if err != nil { return nil, err } return newMappingValueNode(c, keyGroup.Last(), entryTk, key, value) } func (p *parser) parseMapKey(ctx *context, g *TokenGroup) (ast.MapKeyNode, error) { if g.Type != TokenGroupMapKey { return nil, errors.ErrSyntax("unexpected map key", g.RawToken()) } if g.First().Type() == token.MappingKeyType { mapKeyTk := g.First() if mapKeyTk.Group != nil { ctx = ctx.withGroup(mapKeyTk.Group) } key, err := newMappingKeyNode(ctx, mapKeyTk) if err != nil { return nil, err } ctx.goNext() // skip mapping key token if ctx.isTokenNotFound() { return nil, errors.ErrSyntax("could not find value for mapping key", mapKeyTk.RawToken()) } scalar, err := p.parseScalarValue(ctx, ctx.currentToken()) if err != nil { return nil, err } key.Value = scalar keyText := p.mapKeyText(scalar) keyPath := ctx.withChild(keyText).path key.SetPath(keyPath) if err := p.validateMapKey(ctx, key.GetToken(), keyPath, g.Last()); err != nil { return nil, err } p.pathMap[keyPath] = key return key, nil } if g.Last().Type() != token.MappingValueType { return nil, errors.ErrSyntax("expected map key-value delimiter ':'", g.Last().RawToken()) } scalar, err := p.parseScalarValue(ctx, g.First()) if err != nil { return nil, err } key, ok := scalar.(ast.MapKeyNode) if !ok { return nil, errors.ErrSyntax("cannot take map-key node", scalar.GetToken()) } keyText := p.mapKeyText(key) keyPath := ctx.withChild(keyText).path key.SetPath(keyPath) if err := p.validateMapKey(ctx, key.GetToken(), keyPath, g.Last()); err != nil { return nil, err } p.pathMap[keyPath] = key return key, nil } func (p *parser) validateMapKey(ctx *context, tk *token.Token, keyPath string, colonTk *Token) error { if !p.allowDuplicateMapKey { if n, exists := p.pathMap[keyPath]; exists { pos := n.GetToken().Position return errors.ErrSyntax( fmt.Sprintf("mapping key %q already defined at [%d:%d]", tk.Value, pos.Line, pos.Column), tk, ) } } origin := p.removeLeftWhiteSpace(tk.Origin) if ctx.isFlow { if tk.Type == token.StringType { origin = p.removeRightWhiteSpace(origin) if tk.Position.Line+p.newLineCharacterNum(origin) != colonTk.Line() { return errors.ErrSyntax("map key definition includes an implicit line break", tk) } } return nil } if tk.Type != token.StringType && tk.Type != token.SingleQuoteType && tk.Type != token.DoubleQuoteType { return nil } if p.existsNewLineCharacter(origin) { return errors.ErrSyntax("unexpected key name", tk) } return nil } func (p *parser) removeLeftWhiteSpace(src string) string { // CR or LF or CRLF return strings.TrimLeftFunc(src, func(r rune) bool { return r == ' ' || r == '\r' || r == '\n' }) } func (p *parser) removeRightWhiteSpace(src string) string { // CR or LF or CRLF return strings.TrimRightFunc(src, func(r rune) bool { return r == ' ' || r == '\r' || r == '\n' }) } func (p *parser) existsNewLineCharacter(src string) bool { return p.newLineCharacterNum(src) > 0 } func (p *parser) newLineCharacterNum(src string) int { var num int for i := 0; i < len(src); i++ { switch src[i] { case '\r': if len(src) > i+1 && src[i+1] == '\n' { i++ } num++ case '\n': num++ } } return num } func (p *parser) mapKeyText(n ast.Node) string { if n == nil { return "" } switch nn := n.(type) { case *ast.MappingKeyNode: return p.mapKeyText(nn.Value) case *ast.TagNode: return p.mapKeyText(nn.Value) case *ast.AnchorNode: return p.mapKeyText(nn.Value) case *ast.AliasNode: return "" } return n.GetToken().Value } func (p *parser) parseMapValue(ctx *context, key ast.MapKeyNode, colonTk *Token) (ast.Node, error) { tk := ctx.currentToken() if tk == nil { return newNullNode(ctx, ctx.addNullValueToken(colonTk)) } if ctx.isComment() { tk = ctx.nextNotCommentToken() } keyCol := key.GetToken().Position.Column keyLine := key.GetToken().Position.Line if tk.Column() != keyCol && tk.Line() == keyLine && (tk.GroupType() == TokenGroupMapKey || tk.GroupType() == TokenGroupMapKeyValue) { // a: b: // ^ // // a: b: c // ^ return nil, errors.ErrSyntax("mapping value is not allowed in this context", tk.RawToken()) } if tk.Column() == keyCol && p.isMapToken(tk) { // in this case, // ---- // key: // next return newNullNode(ctx, ctx.insertNullToken(colonTk)) } if tk.Line() == keyLine && tk.GroupType() == TokenGroupAnchorName && ctx.nextToken().Column() == keyCol && p.isMapToken(ctx.nextToken()) { // in this case, // ---- // key: &anchor // next group := &TokenGroup{ Type: TokenGroupAnchor, Tokens: []*Token{tk, ctx.createImplicitNullToken(tk)}, } anchor, err := p.parseAnchor(ctx.withGroup(group), group) if err != nil { return nil, err } ctx.goNext() return anchor, nil } if tk.Column() <= keyCol && tk.GroupType() == TokenGroupAnchorName { // key: // &anchor return nil, errors.ErrSyntax("anchor is not allowed in this context", tk.RawToken()) } if tk.Column() <= keyCol && tk.Type() == token.TagType { // key: // !!tag return nil, errors.ErrSyntax("tag is not allowed in this context", tk.RawToken()) } if tk.Column() < keyCol { // in this case, // ---- // key: // next return newNullNode(ctx, ctx.insertNullToken(colonTk)) } if tk.Line() == keyLine && tk.GroupType() == TokenGroupAnchorName && ctx.nextToken().Column() < keyCol { // in this case, // ---- // key: &anchor // next group := &TokenGroup{ Type: TokenGroupAnchor, Tokens: []*Token{tk, ctx.createImplicitNullToken(tk)}, } anchor, err := p.parseAnchor(ctx.withGroup(group), group) if err != nil { return nil, err } ctx.goNext() return anchor, nil } value, err := p.parseToken(ctx, ctx.currentToken()) if err != nil { return nil, err } if err := p.validateAnchorValueInMapOrSeq(value, keyCol); err != nil { return nil, err } return value, nil } func (p *parser) validateAnchorValueInMapOrSeq(value ast.Node, col int) error { anchor, ok := value.(*ast.AnchorNode) if !ok { return nil } tag, ok := anchor.Value.(*ast.TagNode) if !ok { return nil } anchorTk := anchor.GetToken() tagTk := tag.GetToken() if anchorTk.Position.Line == tagTk.Position.Line { // key: // &anchor !!tag // // - &anchor !!tag return nil } if tagTk.Position.Column <= col { // key: &anchor // !!tag // // - &anchor // !!tag return errors.ErrSyntax("tag is not allowed in this context", tagTk) } return nil } func (p *parser) parseAnchor(ctx *context, g *TokenGroup) (*ast.AnchorNode, error) { anchorNameGroup := g.First().Group anchor, err := p.parseAnchorName(ctx.withGroup(anchorNameGroup)) if err != nil { return nil, err } ctx.goNext() if ctx.isTokenNotFound() { return nil, errors.ErrSyntax("could not find anchor value", anchor.GetToken()) } value, err := p.parseToken(ctx, ctx.currentToken()) if err != nil { return nil, err } if _, ok := value.(*ast.AnchorNode); ok { return nil, errors.ErrSyntax("anchors cannot be used consecutively", value.GetToken()) } anchor.Value = value return anchor, nil } func (p *parser) parseAnchorName(ctx *context) (*ast.AnchorNode, error) { anchor, err := newAnchorNode(ctx, ctx.currentToken()) if err != nil { return nil, err } ctx.goNext() if ctx.isTokenNotFound() { return nil, errors.ErrSyntax("could not find anchor value", anchor.GetToken()) } anchorName, err := p.parseScalarValue(ctx, ctx.currentToken()) if err != nil { return nil, err } if anchorName == nil { return nil, errors.ErrSyntax("unexpected anchor. anchor name is not scalar value", ctx.currentToken().RawToken()) } anchor.Name = anchorName return anchor, nil } func (p *parser) parseAlias(ctx *context) (*ast.AliasNode, error) { alias, err := newAliasNode(ctx, ctx.currentToken()) if err != nil { return nil, err } ctx.goNext() if ctx.isTokenNotFound() { return nil, errors.ErrSyntax("could not find alias value", alias.GetToken()) } aliasName, err := p.parseScalarValue(ctx, ctx.currentToken()) if err != nil { return nil, err } if aliasName == nil { return nil, errors.ErrSyntax("unexpected alias. alias name is not scalar value", ctx.currentToken().RawToken()) } alias.Value = aliasName return alias, nil } func (p *parser) parseLiteral(ctx *context) (*ast.LiteralNode, error) { node, err := newLiteralNode(ctx, ctx.currentToken()) if err != nil { return nil, err } ctx.goNext() // skip literal/folded token tk := ctx.currentToken() if tk == nil { value, err := newStringNode(ctx, &Token{Token: token.New("", "", node.Start.Position)}) if err != nil { return nil, err } node.Value = value return node, nil } value, err := p.parseToken(ctx, tk) if err != nil { return nil, err } str, ok := value.(*ast.StringNode) if !ok { return nil, errors.ErrSyntax("unexpected token. required string token", value.GetToken()) } node.Value = str return node, nil } func (p *parser) parseScalarTag(ctx *context) (*ast.TagNode, error) { tag, err := p.parseTag(ctx) if err != nil { return nil, err } if tag.Value == nil { return nil, errors.ErrSyntax("specified not scalar tag", tag.GetToken()) } if _, ok := tag.Value.(ast.ScalarNode); !ok { return nil, errors.ErrSyntax("specified not scalar tag", tag.GetToken()) } return tag, nil } func (p *parser) parseTag(ctx *context) (*ast.TagNode, error) { tagTk := ctx.currentToken() tagRawTk := tagTk.RawToken() node, err := newTagNode(ctx, tagTk) if err != nil { return nil, err } ctx.goNext() comment := p.parseHeadComment(ctx) var tagValue ast.Node if p.secondaryTagDirective != nil { value, err := newStringNode(ctx, ctx.currentToken()) if err != nil { return nil, err } tagValue = value node.Directive = p.secondaryTagDirective } else { value, err := p.parseTagValue(ctx, tagRawTk, ctx.currentToken()) if err != nil { return nil, err } tagValue = value } if err := setHeadComment(comment, tagValue); err != nil { return nil, err } node.Value = tagValue return node, nil } func (p *parser) parseTagValue(ctx *context, tagRawTk *token.Token, tk *Token) (ast.Node, error) { if tk == nil { return newNullNode(ctx, ctx.createImplicitNullToken(&Token{Token: tagRawTk})) } switch token.ReservedTagKeyword(tagRawTk.Value) { case token.MappingTag, token.SetTag: if !p.isMapToken(tk) { return nil, errors.ErrSyntax("could not find map", tk.RawToken()) } if tk.Type() == token.MappingStartType { return p.parseFlowMap(ctx.withFlow(true)) } return p.parseMap(ctx) case token.IntegerTag, token.FloatTag, token.StringTag, token.BinaryTag, token.TimestampTag, token.BooleanTag, token.NullTag: if tk.GroupType() == TokenGroupLiteral || tk.GroupType() == TokenGroupFolded { return p.parseLiteral(ctx.withGroup(tk.Group)) } else if tk.Type() == token.CollectEntryType || tk.Type() == token.MappingValueType { return newTagDefaultScalarValueNode(ctx, tagRawTk) } scalar, err := p.parseScalarValue(ctx, tk) if err != nil { return nil, err } ctx.goNext() return scalar, nil case token.SequenceTag, token.OrderedMapTag: if tk.Type() == token.SequenceStartType { return p.parseFlowSequence(ctx.withFlow(true)) } return p.parseSequence(ctx) } return p.parseToken(ctx, tk) } func (p *parser) parseFlowSequence(ctx *context) (*ast.SequenceNode, error) { node, err := newSequenceNode(ctx, ctx.currentToken(), true) if err != nil { return nil, err } ctx.goNext() // skip SequenceStart token isFirst := true for ctx.next() { tk := ctx.currentToken() if tk.Type() == token.SequenceEndType { node.End = tk.RawToken() break } var entryTk *Token if tk.Type() == token.CollectEntryType { if isFirst { return nil, errors.ErrSyntax("expected sequence element, but found ','", tk.RawToken()) } entryTk = tk ctx.goNext() } else if !isFirst { return nil, errors.ErrSyntax("',' or ']' must be specified", tk.RawToken()) } if tk := ctx.currentToken(); tk.Type() == token.SequenceEndType { // this case is here: "[ elem, ]". // In this case, ignore the last element and break sequence parsing. node.End = tk.RawToken() break } if ctx.isTokenNotFound() { break } ctx := ctx.withIndex(uint(len(node.Values))) value, err := p.parseToken(ctx, ctx.currentToken()) if err != nil { return nil, err } node.Values = append(node.Values, value) seqEntry := ast.SequenceEntry(entryTk.RawToken(), value, nil) if err := setLineComment(ctx, seqEntry, entryTk); err != nil { return nil, err } seqEntry.SetPath(ctx.path) node.Entries = append(node.Entries, seqEntry) isFirst = false } if node.End == nil { return nil, errors.ErrSyntax("sequence end token ']' not found", node.Start) } ctx.goNext() // skip sequence end token. return node, nil } func (p *parser) parseSequence(ctx *context) (*ast.SequenceNode, error) { seqTk := ctx.currentToken() seqNode, err := newSequenceNode(ctx, seqTk, false) if err != nil { return nil, err } tk := seqTk for tk.Type() == token.SequenceEntryType && tk.Column() == seqTk.Column() { seqTk := tk headComment := p.parseHeadComment(ctx) ctx.goNext() // skip sequence entry token ctx := ctx.withIndex(uint(len(seqNode.Values))) value, err := p.parseSequenceValue(ctx, seqTk) if err != nil { return nil, err } seqEntry := ast.SequenceEntry(seqTk.RawToken(), value, headComment) if err := setLineComment(ctx, seqEntry, seqTk); err != nil { return nil, err } seqEntry.SetPath(ctx.path) seqNode.ValueHeadComments = append(seqNode.ValueHeadComments, headComment) seqNode.Values = append(seqNode.Values, value) seqNode.Entries = append(seqNode.Entries, seqEntry) if ctx.isComment() { tk = ctx.nextNotCommentToken() } else { tk = ctx.currentToken() } } if ctx.isComment() { if seqTk.Column() <= ctx.currentToken().Column() { // If the comment is in the same or deeper column as the last element column in sequence value, // treat it as a footer comment for the last element. seqNode.FootComment = p.parseFootComment(ctx, seqTk.Column()) if len(seqNode.Values) != 0 { seqNode.FootComment.SetPath(seqNode.Values[len(seqNode.Values)-1].GetPath()) } } } return seqNode, nil } func (p *parser) parseSequenceValue(ctx *context, seqTk *Token) (ast.Node, error) { tk := ctx.currentToken() if tk == nil { return newNullNode(ctx, ctx.addNullValueToken(seqTk)) } if ctx.isComment() { tk = ctx.nextNotCommentToken() } seqCol := seqTk.Column() seqLine := seqTk.Line() if tk.Column() == seqCol && tk.Type() == token.SequenceEntryType { // in this case, // ---- // - // - return newNullNode(ctx, ctx.insertNullToken(seqTk)) } if tk.Line() == seqLine && tk.GroupType() == TokenGroupAnchorName && ctx.nextToken().Column() == seqCol && ctx.nextToken().Type() == token.SequenceEntryType { // in this case, // ---- // - &anchor // - group := &TokenGroup{ Type: TokenGroupAnchor, Tokens: []*Token{tk, ctx.createImplicitNullToken(tk)}, } anchor, err := p.parseAnchor(ctx.withGroup(group), group) if err != nil { return nil, err } ctx.goNext() return anchor, nil } if tk.Column() <= seqCol && tk.GroupType() == TokenGroupAnchorName { // - // &anchor return nil, errors.ErrSyntax("anchor is not allowed in this sequence context", tk.RawToken()) } if tk.Column() <= seqCol && tk.Type() == token.TagType { // - // !!tag return nil, errors.ErrSyntax("tag is not allowed in this sequence context", tk.RawToken()) } if tk.Column() < seqCol { // in this case, // ---- // - // next return newNullNode(ctx, ctx.insertNullToken(seqTk)) } if tk.Line() == seqLine && tk.GroupType() == TokenGroupAnchorName && ctx.nextToken().Column() < seqCol { // in this case, // ---- // - &anchor // next group := &TokenGroup{ Type: TokenGroupAnchor, Tokens: []*Token{tk, ctx.createImplicitNullToken(tk)}, } anchor, err := p.parseAnchor(ctx.withGroup(group), group) if err != nil { return nil, err } ctx.goNext() return anchor, nil } value, err := p.parseToken(ctx, ctx.currentToken()) if err != nil { return nil, err } if err := p.validateAnchorValueInMapOrSeq(value, seqCol); err != nil { return nil, err } return value, nil } func (p *parser) parseDirective(ctx *context, g *TokenGroup) (*ast.DirectiveNode, error) { directiveNameGroup := g.First().Group directive, err := p.parseDirectiveName(ctx.withGroup(directiveNameGroup)) if err != nil { return nil, err } switch directive.Name.String() { case "YAML": if len(g.Tokens) != 2 { return nil, errors.ErrSyntax("unexpected format YAML directive", g.First().RawToken()) } valueTk := g.Tokens[1] valueRawTk := valueTk.RawToken() value := valueRawTk.Value ver, exists := yamlVersionMap[value] if !exists { return nil, errors.ErrSyntax(fmt.Sprintf("unknown YAML version %q", value), valueRawTk) } if p.yamlVersion != "" { return nil, errors.ErrSyntax("YAML version has already been specified", valueRawTk) } p.yamlVersion = ver versionNode, err := newStringNode(ctx, valueTk) if err != nil { return nil, err } directive.Values = append(directive.Values, versionNode) case "TAG": if len(g.Tokens) != 3 { return nil, errors.ErrSyntax("unexpected format TAG directive", g.First().RawToken()) } tagKey, err := newStringNode(ctx, g.Tokens[1]) if err != nil { return nil, err } if tagKey.Value == "!!" { p.secondaryTagDirective = directive } tagValue, err := newStringNode(ctx, g.Tokens[2]) if err != nil { return nil, err } directive.Values = append(directive.Values, tagKey, tagValue) default: if len(g.Tokens) > 1 { for _, tk := range g.Tokens[1:] { value, err := newStringNode(ctx, tk) if err != nil { return nil, err } directive.Values = append(directive.Values, value) } } } return directive, nil } func (p *parser) parseDirectiveName(ctx *context) (*ast.DirectiveNode, error) { directive, err := newDirectiveNode(ctx, ctx.currentToken()) if err != nil { return nil, err } ctx.goNext() if ctx.isTokenNotFound() { return nil, errors.ErrSyntax("could not find directive value", directive.GetToken()) } directiveName, err := p.parseScalarValue(ctx, ctx.currentToken()) if err != nil { return nil, err } if directiveName == nil { return nil, errors.ErrSyntax("unexpected directive. directive name is not scalar value", ctx.currentToken().RawToken()) } directive.Name = directiveName return directive, nil } func (p *parser) parseComment(ctx *context) (ast.Node, error) { cm := p.parseHeadComment(ctx) if ctx.isTokenNotFound() { return cm, nil } node, err := p.parseToken(ctx, ctx.currentToken()) if err != nil { return nil, err } if err := setHeadComment(cm, node); err != nil { return nil, err } return node, nil } func (p *parser) parseHeadComment(ctx *context) *ast.CommentGroupNode { tks := []*token.Token{} for ctx.isComment() { tks = append(tks, ctx.currentToken().RawToken()) ctx.goNext() } if len(tks) == 0 { return nil } return ast.CommentGroup(tks) } func (p *parser) parseFootComment(ctx *context, col int) *ast.CommentGroupNode { tks := []*token.Token{} for ctx.isComment() && col <= ctx.currentToken().Column() { tks = append(tks, ctx.currentToken().RawToken()) ctx.goNext() } if len(tks) == 0 { return nil } return ast.CommentGroup(tks) } goccy-go-yaml-52dacb8/parser/parser_test.go000066400000000000000000000616641501576637100210610ustar00rootroot00000000000000package parser_test import ( "fmt" "path/filepath" "reflect" "strconv" "strings" "testing" "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/lexer" "github.com/goccy/go-yaml/parser" "github.com/goccy/go-yaml/token" ) func TestParser(t *testing.T) { sources := []string{ "", "null\n", "0_", "{}\n", "v: hi\n", "v: \"true\"\n", "v: \"false\"\n", "v: true\n", "v: false\n", "v: 10\n", "v: -10\n", "v: 42\n", "v: 4294967296\n", "v: \"10\"\n", "v: 0.1\n", "v: 0.99\n", "v: -0.1\n", "v: .inf\n", "v: -.inf\n", "v: .nan\n", "v: null\n", "v: \"\"\n", "v:\n- A\n- B\n", "a: '-'\n", "123\n", "hello: world\n", "a: null\n", "v:\n- A\n- 1\n- B:\n - 2\n - 3\n", "a:\n b: c\n", "a: {x: 1}\n", "t2: 2018-01-09T10:40:47Z\nt4: 2098-01-09T10:40:47Z\n", "a: [1, 2]\n", "a: {b: c, d: e}\n", "a: 3s\n", "a: \n", "a: \"1:1\"\n", "a: 1.2.3.4\n", "a: \"2015-02-24T18:19:39Z\"\n", "a: 'b: c'\n", "a: 'Hello #comment'\n", "a: abc <> ghi", "a: <-\n B\n C\n", "v: |-\n 0\n", "v: |-\n 0\nx: 0", `"a\n1\nb"`, `{"a":"b"}`, `!!map { ? !!str "explicit":!!str "entry", ? !!str "implicit" : !!str "entry", ? !!null "" : !!null "", }`, "\"a\": a\n\"b\": b", "'a': a\n'b': b", "a: \r\n b: 1\r\n", "a_ok: \r bc: 2\r", "a_mk: \n bd: 3\n", "a: :a", "{a: , b: c}", "value: >\n", "value: >\n\n", "value: >\nother:", "value: >\n\nother:", "a:\n-", "a: {foo}", "a: {foo,bar}", ` { a: { b: c }, d: e } `, ` [ a: { b: c }] `, ` { a: { b: c }} `, ` - !tag a: b c: d `, ` a: !tag b: c `, ` a: !tag b: c d: e `, ` a: b: c `, ` foo: xxx --- foo: yyy --- foo: zzz `, ` v: a : 'a' bb : 'a' `, ` v: a : 'x' b : 'y' `, ` v: a : 'x' b : 'y' c : 'z' `, `{a: &a c, *a : b}`, } for idx, src := range sources { t.Run(strconv.Itoa(idx), func(t *testing.T) { f, err := parser.Parse(lexer.Tokenize(src), 0) if err != nil { t.Fatalf("parse error: source [%s]: %+v", src, err) } _ = f.String() // ensure no panic }) } } func TestParseEmptyDocument(t *testing.T) { t.Run("empty document", func(t *testing.T) { f, err := parser.ParseBytes([]byte(""), parser.ParseComments) if err != nil { t.Fatal(err) } got := f.String() expected := "\n" if got != expected { t.Fatalf("failed to parse comment:\nexpected:\n%q\ngot:\n%q", expected, got) } }) t.Run("empty document with comment (parse comment = off)", func(t *testing.T) { f, err := parser.ParseBytes([]byte("# comment"), 0) if err != nil { t.Fatal(err) } got := f.String() expected := "\n" if got != expected { t.Fatalf("failed to parse comment:\nexpected:\n%q\ngot:\n%q", expected, got) } }) t.Run("empty document with comment (parse comment = on)", func(t *testing.T) { f, err := parser.ParseBytes([]byte("# comment"), parser.ParseComments) if err != nil { t.Fatal(err) } got := f.String() expected := "# comment\n" if got != expected { t.Fatalf("failed to parse comment:\nexpected:\n%q\ngot:\n%q", expected, got) } }) } func TestParseComplicatedDocument(t *testing.T) { tests := []struct { source string expect string }{ { ` american: - Boston Red Sox - Detroit Tigers - New York Yankees national: - New York Mets - Chicago Cubs - Atlanta Braves `, ` american: - Boston Red Sox - Detroit Tigers - New York Yankees national: - New York Mets - Chicago Cubs - Atlanta Braves `, }, { ` a: b: c d: e f: g h: i: j k: l: m n: o p: q r: s `, ` a: b: c d: e f: g h: i: j k: l: m n: o p: q r: s `, }, { ` - a: - b - c - d `, ` - a: - b - c - d `, }, { ` - a - b - c - d - e - f `, ` - a - b - c - d - e - f `, }, { ` a: 0 - 1 `, ` a: 0 - 1 `, }, {` - a: b: c d: e - f: g: h `, ` - a: b: c d: e - f: g: h `, }, { ` a: b c d: e `, ` a: b c d: e `, }, { ` a b c `, ` a b c `, }, { ` a: - b - c `, ` a: - b - c `, }, { ` - a : b: c `, ` - a: b: c `, }, { ` - a: b c d hoge: fuga `, ` - a: b c d hoge: fuga `, }, { ` - a # ' " # - : % - b # " # - : % ' - c # # - : % ' " - d # - : % ' " # - e # : % ' " # - - f # % ' : # - : `, ` - a - b - c - d - e - f `, }, { ` # comment a: # comment # comment b: c # comment # comment d: e # comment # comment `, ` a: b: c d: e `, }, { ` a: b#notcomment `, ` a: b#notcomment `, }, { ` anchored: &anchor foo aliased: *anchor `, ` anchored: &anchor foo aliased: *anchor `, }, { ` --- - &CENTER { x: 1, y: 2 } - &LEFT { x: 0, y: 2 } - &BIG { r: 10 } - &SMALL { r: 1 } # All the following maps are equal: - # Explicit keys x: 1 y: 2 r: 10 label: center/big - # Merge one map << : *CENTER r: 10 label: center/big - # Merge multiple maps << : [ *CENTER, *BIG ] label: center/big - # Override << : [ *BIG, *LEFT, *SMALL ] x: 1 label: center/big `, ` --- - &CENTER {x: 1, y: 2} - &LEFT {x: 0, y: 2} - &BIG {r: 10} - &SMALL {r: 1} - x: 1 y: 2 r: 10 label: center/big - <<: *CENTER r: 10 label: center/big - <<: [*CENTER, *BIG] label: center/big - <<: [*BIG, *LEFT, *SMALL] x: 1 label: center/big `, }, { ` a: - - b - - c - d `, ` a: - - b - - c - d `, }, { ` a: b: c: d e: f: g h: i j: k `, ` a: b: c: d e: f: g h: i j: k `, }, { ` --- a: 1 b: 2 ... --- c: 3 d: 4 ... `, ` --- a: 1 b: 2 ... --- c: 3 d: 4 ... `, }, { ` a: b: | { [ 1, 2 ] } c: d `, ` a: b: | { [ 1, 2 ] } c: d `, }, { ` | hoge fuga piyo`, ` | hoge fuga piyo `, }, { ` v: | a b c`, ` v: | a b c `, }, { ` a: | bbbbbbb ccccccc d: eeeeeeeeeeeeeeeee `, ` a: | bbbbbbb ccccccc d: eeeeeeeeeeeeeeeee `, }, { ` a: b c `, ` a: b c `, }, { ` a: b: c `, ` a: b: c `, }, { ` a: b c: d `, ` a: b c: d `, }, { ` - ab - cd - ef - gh `, ` - ab - cd - ef - gh `, }, { ` - 0 - 1 - 2 - 3 `, ` - 0 - 1 - 2 - 3 `, }, { ` a - b - c: value `, ` a - b - c: value `, }, { ` a: - b: c d: e - f: g h: i `, ` a: - b: c d: e - f: g h: i `, }, { ` a: |- value b: c `, ` a: |- value b: c `, }, { ` a: |+ value b: c `, ` a: |+ value b: c `, }, { ` - key1: val key2: ( foo + bar ) `, ` - key1: val key2: ( foo + bar ) `, }, { ` "a": b 'c': d "e": "f" g: "h" i: 'j' `, ` "a": b 'c': d "e": "f" g: "h" i: 'j' `, }, { ` a: - |2 b c: d `, ` a: - |2 b c: d `, }, { ` a: b: &anchor c: &anchor2 d: e `, ` a: b: &anchor c: &anchor2 d: e `, }, } for _, test := range tests { t.Run(test.source, func(t *testing.T) { tokens := lexer.Tokenize(test.source) f, err := parser.Parse(tokens, 0) if err != nil { t.Fatalf("%+v", err) } got := f.String() if got != strings.TrimPrefix(test.expect, "\n") { t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(test.expect, "\n"), got) } var v Visitor for _, doc := range f.Docs { ast.Walk(&v, doc.Body) } expect := fmt.Sprintf("\n%+v", f) if test.expect != expect { tokens.Dump() t.Fatalf("unexpected output: [%s] != [%s]", test.expect, expect) } }) } } func TestParseWhitespace(t *testing.T) { tests := []struct { source string expect string }{ { ` a: b c: d e: f g: h `, ` a: b c: d e: f g: h `, }, { ` a: - b: c d: e - f: g h: i `, ` a: - b: c d: e - f: g h: i `, }, { ` a: - b: c d: e - f: g h: i `, ` a: - b: c d: e - f: g h: i `, }, { ` a: - b: c d: e - f: g h: i `, ` a: - b: c d: e - f: g h: i `, }, { ` a: # comment 1 - b: c d: e # comment 2 - f: g h: i `, ` a: # comment 1 - b: c d: e # comment 2 - f: g h: i `, }, { ` a: # comment 1 - b: c # comment 2 d: e # comment 3 # comment 4 - f: g h: i # comment 5 `, ` a: # comment 1 - b: c # comment 2 d: e # comment 3 # comment 4 - f: g h: i # comment 5 `, }, { ` a: # comment 1 - b: c # comment 2 d: e # comment 3 # comment 4 - f: | g g h: i # comment 5 `, ` a: # comment 1 - b: c # comment 2 d: e # comment 3 # comment 4 - f: | g g h: i # comment 5 `, }, { ` a: # comment 1 - b: c # comment 2 d: e # comment 3 # comment 4 - f: | asd def h: i # comment 5 `, ` a: # comment 1 - b: c # comment 2 d: e # comment 3 # comment 4 - f: | asd def h: i # comment 5 `, }, { ` - b: c d: e - f: g h: i # comment 4 `, ` - b: c d: e - f: g h: i # comment 4 `, }, { ` a: null b: null d: e `, ` a: null b: null d: e `, }, { ` foo: bar: null # comment baz: 1 `, ` foo: bar: null # comment baz: 1 `, }, { ` foo: bar: null # comment baz: 1 `, ` foo: bar: null # comment baz: 1 `, }, { ` { "apiVersion": "apps/v1", "kind": "Deployment", "metadata": { "name": "foo", "labels": { "app": "bar" } }, "spec": { "replicas": 3, "selector": { "matchLabels": { "app": "bar" } }, "template": { "metadata": { "labels": { "app": "bar" } } } } } `, ` {"apiVersion": "apps/v1", "kind": "Deployment", "metadata": {"name": "foo", "labels": {"app": "bar"}}, "spec": {"replicas": 3, "selector": {"matchLabels": {"app": "bar"}}, "template": {"metadata": {"labels": {"app": "bar"}}}}} `, }, } for _, test := range tests { t.Run(test.source, func(t *testing.T) { f, err := parser.ParseBytes([]byte(test.source), parser.ParseComments) if err != nil { t.Fatal(err) } got := f.String() if got != strings.TrimPrefix(test.expect, "\n") { t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(test.expect, "\n"), got) } }) } } func TestNewLineChar(t *testing.T) { for _, f := range []string{ "lf.yml", "cr.yml", "crlf.yml", } { ast, err := parser.ParseFile(filepath.Join("testdata", f), 0) if err != nil { t.Fatalf("%+v", err) } actual := fmt.Sprintf("%v", ast) expect := `a: "a" b: 1 ` if expect != actual { t.Fatalf("unexpected result\nexpected:\n%s\ngot:\n%s", expect, actual) } } } func TestSyntaxError(t *testing.T) { tests := []struct { source string expect string }{ { ` a: - b c: d e: f g: h`, ` [3:3] unexpected key name 2 | a: > 3 | - b 4 | c: d ^ 5 | e: f 6 | g: h`, }, { ` a - b: c`, ` [2:1] unexpected key name > 2 | a 3 | - b: c ^ `, }, { `%YAML 1.1 {}`, ` [1:1] unexpected directive value. document not started > 1 | %YAML 1.1 {} ^ `, }, { `{invalid`, ` [1:2] could not find flow map content > 1 | {invalid ^ `, }, { `{ "key": "value" `, ` [1:1] could not find flow mapping end token '}' > 1 | { "key": "value" ^ `, }, { ` a: |invalidopt foo `, ` [2:4] invalid header option: "invalidopt" > 2 | a: |invalidopt ^ 3 | foo`, }, { ` a: 1 b `, ` [3:1] non-map value is specified 2 | a: 1 > 3 | b ^ `, }, { ` a: 'b' c: d `, ` [3:3] value is not allowed in this context. map key-value is pre-defined 2 | a: 'b' > 3 | c: d ^ `, }, { ` a: 'b' - c `, ` [3:3] value is not allowed in this context. map key-value is pre-defined 2 | a: 'b' > 3 | - c ^ `, }, { ` a: 'b' # comment - c `, ` [4:3] value is not allowed in this context. map key-value is pre-defined 2 | a: 'b' 3 | # comment > 4 | - c ^ `, }, { ` a: 1 b - c `, ` [3:1] non-map value is specified 2 | a: 1 > 3 | b ^ 4 | - c`, }, { `a: [`, ` [1:4] sequence end token ']' not found > 1 | a: [ ^ `, }, { `a: ]`, ` [1:4] could not find '[' character corresponding to ']' > 1 | a: ] ^ `, }, { `a: [ [1] [2] [3] ]`, ` [1:10] ',' or ']' must be specified > 1 | a: [ [1] [2] [3] ] ^ `, }, { ` a: - b: - `, ` [2:4] block sequence entries are not allowed in this context > 2 | a: - ^ 3 | b: -`, }, { ` a: - 1 b: - 2 `, ` [2:4] block sequence entries are not allowed in this context > 2 | a: - 1 ^ 3 | b: - 2`, }, { `a: 'foobarbaz`, ` [1:4] could not find end character of single-quoted text > 1 | a: 'foobarbaz ^ `, }, { `a: "\"key\": \"value:\"`, ` [1:4] could not find end character of double-quoted text > 1 | a: "\"key\": \"value:\" ^ `, }, { `foo: [${should not be allowed}]`, ` [1:8] ',' or ']' must be specified > 1 | foo: [${should not be allowed}] ^ `, }, { `foo: [$[should not be allowed]]`, ` [1:8] ',' or ']' must be specified > 1 | foo: [$[should not be allowed]] ^ `, }, { ">\n>", ` [2:1] could not find multi-line content 1 | > > 2 | > ^ `, }, { ">\n1", ` [2:1] could not find multi-line content 1 | > > 2 | 1 ^ `, }, { "|\n1", ` [2:1] could not find multi-line content 1 | | > 2 | 1 ^ `, }, { "a: >3\n 1", ` [2:3] invalid number of indent is specified in the multi-line header 1 | a: >3 > 2 | 1 ^ `, }, { ` a: - | b c: d `, ` [5:5] value is not allowed in this context 2 | a: 3 | - | 4 | b > 5 | c: d ^ `, }, { ` a: - | b c: d: e `, ` [5:5] value is not allowed in this context 2 | a: 3 | - | 4 | b > 5 | c: ^ 6 | d: e`, }, { "key: [@val]", ` [1:7] '@' is a reserved character > 1 | key: [@val] ^ `, }, { "key: [`val]", "\n[1:7] '`' is a reserved character\n> 1 | key: [`val]\n ^\n", }, { `{a: b}: v`, ` [1:7] found an invalid key for this map > 1 | {a: b}: v ^ `, }, { `[a]: v`, ` [1:4] found an invalid key for this map > 1 | [a]: v ^ `, }, { ` foo: bar: foo: 2 baz: foo: 3 foo: 2 `, ` [7:1] mapping key "foo" already defined at [2:1] 4 | foo: 2 5 | baz: 6 | foo: 3 > 7 | foo: 2 ^ `, }, { ` foo: bar: foo: 2 baz: foo: 3 foo: 4 `, ` [7:5] mapping key "foo" already defined at [6:5] 4 | foo: 2 5 | baz: 6 | foo: 3 > 7 | foo: 4 ^ `, }, { `{"000":0000A,`, ` [1:13] could not find flow map content > 1 | {"000":0000A, ^ `, }, } for _, test := range tests { t.Run(test.source, func(t *testing.T) { _, err := parser.ParseBytes([]byte(test.source), 0) if err == nil { t.Fatal("cannot catch syntax error") } actual := "\n" + err.Error() if test.expect != actual { t.Fatalf("expected: [%s] but got [%s]", test.expect, actual) } }) } } func TestComment(t *testing.T) { tests := []struct { name string yaml string expected string }{ { name: "map with comment", yaml: ` # commentA a: #commentB # commentC b: c # commentD # commentE d: e # commentF # commentG f: g # commentH # commentI f: g # commentJ # commentK `, }, { name: "sequence with comment", yaml: ` # commentA - a # commentB # commentC - b: # commentD # commentE - d # commentF - e # commentG # commentH `, }, { name: "anchor and alias", yaml: ` a: &x b # commentA c: *x # commentB `, }, { name: "multiline", yaml: ` # foo comment # foo comment2 foo: # map key comment # bar above comment # bar above comment2 bar: 10 # comment for bar # baz above comment # baz above comment2 baz: bbbb # comment for baz piyo: # sequence key comment # sequence1 above comment 1 # sequence1 above comment 2 - sequence1 # sequence1 # sequence2 above comment 1 # sequence2 above comment 2 - sequence2 # sequence2 # sequence3 above comment 1 # sequence3 above comment 2 - false # sequence3 # foo2 comment # foo2 comment2 foo2: &anchor text # anchor comment # foo3 comment # foo3 comment2 foo3: *anchor # alias comment `, }, { name: "literal", yaml: ` foo: | # comment x: 42 `, }, { name: "folded", yaml: ` foo: > # comment x: 42 `, }, { name: "unattached comment", yaml: ` # This comment is in its own document --- a: b `, }, { name: "map with misaligned indentation in comments", yaml: ` # commentA a: #commentB # commentC b: c # commentD # commentE d: e # commentF # commentG `, expected: ` # commentA a: #commentB # commentC b: c # commentD # commentE d: e # commentF # commentG `, }, { name: "sequence with misaligned indentation in comments", yaml: ` # commentA - a # commentB # commentC - b: # commentD # commentE - d # commentF # commentG - e # commentG # commentH `, expected: ` # commentA - a # commentB # commentC - b: # commentD # commentE - d # commentF # commentG - e # commentG # commentH `, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { f, err := parser.ParseBytes([]byte(test.yaml), parser.ParseComments) if err != nil { t.Fatalf("%+v", err) } got := "\n" + f.String() expected := test.yaml if test.expected != "" { expected = test.expected } if expected != got { t.Fatalf("expected:%s\ngot:%s", expected, got) } }) } } func TestCommentWithNull(t *testing.T) { t.Run("same line", func(t *testing.T) { content := ` foo: bar: # comment baz: 1 ` expected := ` foo: bar: # comment baz: 1` f, err := parser.ParseBytes([]byte(content), parser.ParseComments) if err != nil { t.Fatal(err) } if len(f.Docs) != 1 { t.Fatal("failed to parse content with same line comment") } got := f.Docs[0].String() if got != strings.TrimPrefix(expected, "\n") { t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(expected, "\n"), got) } }) t.Run("next line", func(t *testing.T) { content := ` foo: bar: # comment baz: 1 ` expected := ` foo: bar: # comment baz: 1` f, err := parser.ParseBytes([]byte(content), parser.ParseComments) if err != nil { t.Fatal(err) } if len(f.Docs) != 1 { t.Fatal("failed to parse content with next line comment") } got := f.Docs[0].String() if got != strings.TrimPrefix(expected, "\n") { t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(expected, "\n"), got) } }) t.Run("next line and different indent", func(t *testing.T) { content := ` foo: bar: # comment baz: 1` f, err := parser.ParseBytes([]byte(content), parser.ParseComments) if err != nil { t.Fatal(err) } if len(f.Docs) != 1 { t.Fatal("failed to parse content with next line comment") } expected := ` foo: bar: # comment baz: 1` got := f.Docs[0].String() if got != strings.TrimPrefix(expected, "\n") { t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(expected, "\n"), got) } }) } func TestSequenceComment(t *testing.T) { content := ` foo: - # comment bar: 1 baz: - xxx ` f, err := parser.ParseBytes([]byte(content), parser.ParseComments) if err != nil { t.Fatal(err) } if len(f.Docs) != 1 { t.Fatal("failed to parse content with next line with sequence") } expected := ` foo: # comment - bar: 1 baz: - xxx` got := f.Docs[0].String() if got != strings.TrimPrefix(expected, "\n") { t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", strings.TrimPrefix(expected, "\n"), got) } t.Run("foo[0].bar", func(t *testing.T) { path, err := yaml.PathString("$.foo[0].bar") if err != nil { t.Fatal(err) } v, err := path.FilterFile(f) if err != nil { t.Fatal(err) } if v.String() != "1" { t.Fatal("failed to get foo[0].bar value") } }) t.Run("baz[0]", func(t *testing.T) { path, err := yaml.PathString("$.baz[0]") if err != nil { t.Fatal(err) } v, err := path.FilterFile(f) if err != nil { t.Fatal(err) } if v.String() != "xxx" { t.Fatal("failed to get baz[0] value") } }) } func TestCommentWithMap(t *testing.T) { yml := ` single: # foo comment foo: bar multiple: # a comment a: b # c comment c: d ` file, err := parser.ParseBytes([]byte(yml), parser.ParseComments) if err != nil { t.Fatal(err) } if len(file.Docs) == 0 { t.Fatal("cannot get file docs") } if file.Docs[0].Body == nil { t.Fatal("cannot get docs body") } mapNode, ok := file.Docs[0].Body.(*ast.MappingNode) if !ok { t.Fatalf("failed to get map node. got: %T\n", file.Docs[0].Body) } if len(mapNode.Values) != 2 { t.Fatalf("failed to get map values. got %d", len(mapNode.Values)) } singleNode, ok := mapNode.Values[0].Value.(*ast.MappingNode) if !ok { t.Fatalf("failed to get single node. got %T", mapNode.Values[0].Value) } if len(singleNode.Values) != 1 { t.Fatalf("failed to get single node values. got %d", len(singleNode.Values)) } if singleNode.Values[0].GetComment().GetToken().Value != " foo comment" { t.Fatalf("failed to get comment from single. got %q", singleNode.GetComment().GetToken().Value) } multiNode, ok := mapNode.Values[1].Value.(*ast.MappingNode) if !ok { t.Fatalf("failed to get multiple node. got: %T", mapNode.Values[1]) } if multiNode.GetComment() != nil { t.Fatalf("found unexpected comment") } if len(multiNode.Values) != 2 { t.Fatalf("failed to get multiple node values. got %d", len(multiNode.Values)) } if multiNode.Values[0].GetComment().GetToken().Value != " a comment" { t.Fatalf("failed to get comment from multiple[0]. got %q", multiNode.Values[0].GetComment().GetToken().Value) } if multiNode.Values[1].GetComment().GetToken().Value != " c comment" { t.Fatalf("failed to get comment from multiple[1]. got %q", multiNode.Values[1].GetComment().GetToken().Value) } } func TestInFlowStyle(t *testing.T) { type inFlowStyle interface { SetIsFlowStyle(bool) } tests := []struct { source string expect string }{ { ` - foo - bar - baz `, `[foo, bar, baz] `, }, { ` foo: bar baz: fizz `, `{foo: bar, baz: fizz} `, }, { ` foo: - bar - baz - fizz: buzz `, `{foo: [bar, baz, {fizz: buzz}]} `, }, } for _, test := range tests { t.Run(test.source, func(t *testing.T) { f, err := parser.ParseBytes([]byte(test.source), parser.ParseComments) if err != nil { t.Fatal(err) } if len(f.Docs) != 1 { t.Fatal("failed to parse content") } ifs, ok := f.Docs[0].Body.(inFlowStyle) if !ok { t.Fatalf("failed to get inFlowStyle. got: %T", f.Docs[0].Body) } ifs.SetIsFlowStyle(true) got := f.String() if got != test.expect { t.Fatalf("failed to parse comment:\nexpected:\n%s\ngot:\n%s", test.expect, got) } }) } } func TestNodePath(t *testing.T) { yml := ` a: # commentA b: # commentB c: foo # commentC d: bar # commentD e: baz # commentE f: # commentF g: hoge # commentG h: # commentH - list1 # comment list1 - list2 # comment list2 - list3 # comment list3 i: fuga # commentI j: piyo # commentJ k.l.m.n: moge # commentKLMN o#p: hogera # commentOP q#.r: hogehoge # commentQR ` f, err := parser.ParseBytes([]byte(yml), parser.ParseComments) if err != nil { t.Fatalf("%+v", err) } var capturer pathCapturer for _, doc := range f.Docs { ast.Walk(&capturer, doc.Body) } commentPaths := []string{} for i := 0; i < capturer.capturedNum; i++ { if capturer.orderedTypes[i] == ast.CommentType { commentPaths = append(commentPaths, capturer.orderedPaths[i]) } } expectedPaths := []string{ "$.a", "$.a.b", "$.a.b.c", "$.a.b.d", "$.a.b.e", "$.a.f", "$.a.f.g", "$.a.h", "$.a.h[0]", "$.a.h[1]", "$.a.h[2]", "$.a.i", "$.j", "$.'k.l.m.n'", "$.o#p", "$.'q#.r'", } if !reflect.DeepEqual(expectedPaths, commentPaths) { t.Fatalf("failed to get YAMLPath to the comment node:\nexpected[%s]\ngot [%s]", expectedPaths, commentPaths) } } type pathCapturer struct { capturedNum int orderedPaths []string orderedTypes []ast.NodeType orderedTokens []*token.Token } func (c *pathCapturer) Visit(node ast.Node) ast.Visitor { c.capturedNum++ c.orderedPaths = append(c.orderedPaths, node.GetPath()) c.orderedTypes = append(c.orderedTypes, node.Type()) c.orderedTokens = append(c.orderedTokens, node.GetToken()) return c } type Visitor struct{} func (v *Visitor) Visit(node ast.Node) ast.Visitor { tk := node.GetToken() tk.Prev = nil tk.Next = nil return v } goccy-go-yaml-52dacb8/parser/testdata/000077500000000000000000000000001501576637100177735ustar00rootroot00000000000000goccy-go-yaml-52dacb8/parser/testdata/cr.yml000066400000000000000000000000151501576637100211160ustar00rootroot00000000000000a: "a" b: 1 goccy-go-yaml-52dacb8/parser/testdata/crlf.yml000066400000000000000000000000201501576637100214340ustar00rootroot00000000000000a: "a" b: 1 goccy-go-yaml-52dacb8/parser/testdata/lf.yml000066400000000000000000000000151501576637100211130ustar00rootroot00000000000000a: "a" b: 1 goccy-go-yaml-52dacb8/parser/token.go000066400000000000000000000405151501576637100176360ustar00rootroot00000000000000package parser import ( "fmt" "os" "strings" "github.com/goccy/go-yaml/internal/errors" "github.com/goccy/go-yaml/token" ) type TokenGroupType int const ( TokenGroupNone TokenGroupType = iota TokenGroupDirective TokenGroupDirectiveName TokenGroupDocument TokenGroupDocumentBody TokenGroupAnchor TokenGroupAnchorName TokenGroupAlias TokenGroupLiteral TokenGroupFolded TokenGroupScalarTag TokenGroupMapKey TokenGroupMapKeyValue ) func (t TokenGroupType) String() string { switch t { case TokenGroupNone: return "none" case TokenGroupDirective: return "directive" case TokenGroupDirectiveName: return "directive_name" case TokenGroupDocument: return "document" case TokenGroupDocumentBody: return "document_body" case TokenGroupAnchor: return "anchor" case TokenGroupAnchorName: return "anchor_name" case TokenGroupAlias: return "alias" case TokenGroupLiteral: return "literal" case TokenGroupFolded: return "folded" case TokenGroupScalarTag: return "scalar_tag" case TokenGroupMapKey: return "map_key" case TokenGroupMapKeyValue: return "map_key_value" } return "none" } type Token struct { Token *token.Token Group *TokenGroup LineComment *token.Token } func (t *Token) RawToken() *token.Token { if t == nil { return nil } if t.Token != nil { return t.Token } return t.Group.RawToken() } func (t *Token) Type() token.Type { if t == nil { return 0 } if t.Token != nil { return t.Token.Type } return t.Group.TokenType() } func (t *Token) GroupType() TokenGroupType { if t == nil { return TokenGroupNone } if t.Token != nil { return TokenGroupNone } return t.Group.Type } func (t *Token) Line() int { if t == nil { return 0 } if t.Token != nil { return t.Token.Position.Line } return t.Group.Line() } func (t *Token) Column() int { if t == nil { return 0 } if t.Token != nil { return t.Token.Position.Column } return t.Group.Column() } func (t *Token) SetGroupType(typ TokenGroupType) { if t.Group == nil { return } t.Group.Type = typ } func (t *Token) Dump() { ctx := new(groupTokenRenderContext) if t.Token != nil { fmt.Fprint(os.Stdout, t.Token.Value) return } t.Group.dump(ctx) fmt.Fprintf(os.Stdout, "\n") } func (t *Token) dump(ctx *groupTokenRenderContext) { if t.Token != nil { fmt.Fprint(os.Stdout, t.Token.Value) return } t.Group.dump(ctx) } type groupTokenRenderContext struct { num int } type TokenGroup struct { Type TokenGroupType Tokens []*Token } func (g *TokenGroup) First() *Token { if len(g.Tokens) == 0 { return nil } return g.Tokens[0] } func (g *TokenGroup) Last() *Token { if len(g.Tokens) == 0 { return nil } return g.Tokens[len(g.Tokens)-1] } func (g *TokenGroup) dump(ctx *groupTokenRenderContext) { num := ctx.num fmt.Fprint(os.Stdout, colorize(num, "(")) ctx.num++ for _, tk := range g.Tokens { tk.dump(ctx) } fmt.Fprint(os.Stdout, colorize(num, ")")) } func (g *TokenGroup) RawToken() *token.Token { if len(g.Tokens) == 0 { return nil } return g.Tokens[0].RawToken() } func (g *TokenGroup) Line() int { if len(g.Tokens) == 0 { return 0 } return g.Tokens[0].Line() } func (g *TokenGroup) Column() int { if len(g.Tokens) == 0 { return 0 } return g.Tokens[0].Column() } func (g *TokenGroup) TokenType() token.Type { if len(g.Tokens) == 0 { return 0 } return g.Tokens[0].Type() } func CreateGroupedTokens(tokens token.Tokens) ([]*Token, error) { var err error tks := newTokens(tokens) tks = createLineCommentTokenGroups(tks) tks, err = createLiteralAndFoldedTokenGroups(tks) if err != nil { return nil, err } tks, err = createAnchorAndAliasTokenGroups(tks) if err != nil { return nil, err } tks, err = createScalarTagTokenGroups(tks) if err != nil { return nil, err } tks, err = createAnchorWithScalarTagTokenGroups(tks) if err != nil { return nil, err } tks, err = createMapKeyTokenGroups(tks) if err != nil { return nil, err } tks = createMapKeyValueTokenGroups(tks) tks, err = createDirectiveTokenGroups(tks) if err != nil { return nil, err } tks, err = createDocumentTokens(tks) if err != nil { return nil, err } return tks, nil } func newTokens(tks token.Tokens) []*Token { ret := make([]*Token, 0, len(tks)) for _, tk := range tks { ret = append(ret, &Token{Token: tk}) } return ret } func createLineCommentTokenGroups(tokens []*Token) []*Token { ret := make([]*Token, 0, len(tokens)) for i := 0; i < len(tokens); i++ { tk := tokens[i] switch tk.Type() { case token.CommentType: if i > 0 && tokens[i-1].Line() == tk.Line() { tokens[i-1].LineComment = tk.RawToken() } else { ret = append(ret, tk) } default: ret = append(ret, tk) } } return ret } func createLiteralAndFoldedTokenGroups(tokens []*Token) ([]*Token, error) { ret := make([]*Token, 0, len(tokens)) for i := 0; i < len(tokens); i++ { tk := tokens[i] switch tk.Type() { case token.LiteralType: tks := []*Token{tk} if i+1 < len(tokens) { tks = append(tks, tokens[i+1]) } ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupLiteral, Tokens: tks, }, }) i++ case token.FoldedType: tks := []*Token{tk} if i+1 < len(tokens) { tks = append(tks, tokens[i+1]) } ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupFolded, Tokens: tks, }, }) i++ default: ret = append(ret, tk) } } return ret, nil } func createAnchorAndAliasTokenGroups(tokens []*Token) ([]*Token, error) { ret := make([]*Token, 0, len(tokens)) for i := 0; i < len(tokens); i++ { tk := tokens[i] switch tk.Type() { case token.AnchorType: if i+1 >= len(tokens) { return nil, errors.ErrSyntax("undefined anchor name", tk.RawToken()) } if i+2 >= len(tokens) { return nil, errors.ErrSyntax("undefined anchor value", tk.RawToken()) } anchorName := &Token{ Group: &TokenGroup{ Type: TokenGroupAnchorName, Tokens: []*Token{tk, tokens[i+1]}, }, } valueTk := tokens[i+2] if tk.Line() == valueTk.Line() && valueTk.Type() == token.SequenceEntryType { return nil, errors.ErrSyntax("sequence entries are not allowed after anchor on the same line", valueTk.RawToken()) } if tk.Line() == valueTk.Line() && isScalarType(valueTk) { ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupAnchor, Tokens: []*Token{anchorName, valueTk}, }, }) i++ } else { ret = append(ret, anchorName) } i++ case token.AliasType: if i+1 == len(tokens) { return nil, errors.ErrSyntax("undefined alias name", tk.RawToken()) } ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupAlias, Tokens: []*Token{tk, tokens[i+1]}, }, }) i++ default: ret = append(ret, tk) } } return ret, nil } func createScalarTagTokenGroups(tokens []*Token) ([]*Token, error) { ret := make([]*Token, 0, len(tokens)) for i := 0; i < len(tokens); i++ { tk := tokens[i] if tk.Type() != token.TagType { ret = append(ret, tk) continue } tag := tk.RawToken() if strings.HasPrefix(tag.Value, "!!") { // secondary tag. switch token.ReservedTagKeyword(tag.Value) { case token.IntegerTag, token.FloatTag, token.StringTag, token.BinaryTag, token.TimestampTag, token.BooleanTag, token.NullTag: if len(tokens) <= i+1 { ret = append(ret, tk) continue } if tk.Line() != tokens[i+1].Line() { ret = append(ret, tk) continue } if tokens[i+1].GroupType() == TokenGroupAnchorName { ret = append(ret, tk) continue } if isScalarType(tokens[i+1]) { ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupScalarTag, Tokens: []*Token{tk, tokens[i+1]}, }, }) i++ } else { ret = append(ret, tk) } case token.MergeTag: if len(tokens) <= i+1 { ret = append(ret, tk) continue } if tk.Line() != tokens[i+1].Line() { ret = append(ret, tk) continue } if tokens[i+1].GroupType() == TokenGroupAnchorName { ret = append(ret, tk) continue } if tokens[i+1].Type() != token.MergeKeyType { return nil, errors.ErrSyntax("could not find merge key", tokens[i+1].RawToken()) } ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupScalarTag, Tokens: []*Token{tk, tokens[i+1]}, }, }) i++ default: ret = append(ret, tk) } } else { if len(tokens) <= i+1 { ret = append(ret, tk) continue } if tk.Line() != tokens[i+1].Line() { ret = append(ret, tk) continue } if tokens[i+1].GroupType() == TokenGroupAnchorName { ret = append(ret, tk) continue } if isFlowType(tokens[i+1]) { ret = append(ret, tk) continue } ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupScalarTag, Tokens: []*Token{tk, tokens[i+1]}, }, }) i++ } } return ret, nil } func createAnchorWithScalarTagTokenGroups(tokens []*Token) ([]*Token, error) { ret := make([]*Token, 0, len(tokens)) for i := 0; i < len(tokens); i++ { tk := tokens[i] switch tk.GroupType() { case TokenGroupAnchorName: if i+1 >= len(tokens) { return nil, errors.ErrSyntax("undefined anchor value", tk.RawToken()) } valueTk := tokens[i+1] if tk.Line() == valueTk.Line() && valueTk.GroupType() == TokenGroupScalarTag { ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupAnchor, Tokens: []*Token{tk, tokens[i+1]}, }, }) i++ } else { ret = append(ret, tk) } default: ret = append(ret, tk) } } return ret, nil } func createMapKeyTokenGroups(tokens []*Token) ([]*Token, error) { tks, err := createMapKeyByMappingKey(tokens) if err != nil { return nil, err } return createMapKeyByMappingValue(tks) } func createMapKeyByMappingKey(tokens []*Token) ([]*Token, error) { ret := make([]*Token, 0, len(tokens)) for i := 0; i < len(tokens); i++ { tk := tokens[i] switch tk.Type() { case token.MappingKeyType: if i+1 >= len(tokens) { return nil, errors.ErrSyntax("undefined map key", tk.RawToken()) } ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupMapKey, Tokens: []*Token{tk, tokens[i+1]}, }, }) i++ default: ret = append(ret, tk) } } return ret, nil } func createMapKeyByMappingValue(tokens []*Token) ([]*Token, error) { ret := make([]*Token, 0, len(tokens)) for i := 0; i < len(tokens); i++ { tk := tokens[i] switch tk.Type() { case token.MappingValueType: if i == 0 { return nil, errors.ErrSyntax("unexpected key name", tk.RawToken()) } mapKeyTk := tokens[i-1] if isNotMapKeyType(mapKeyTk) { return nil, errors.ErrSyntax("found an invalid key for this map", tokens[i].RawToken()) } newTk := &Token{Token: mapKeyTk.Token, Group: mapKeyTk.Group} mapKeyTk.Token = nil mapKeyTk.Group = &TokenGroup{ Type: TokenGroupMapKey, Tokens: []*Token{newTk, tk}, } default: ret = append(ret, tk) } } return ret, nil } func createMapKeyValueTokenGroups(tokens []*Token) []*Token { ret := make([]*Token, 0, len(tokens)) for i := 0; i < len(tokens); i++ { tk := tokens[i] switch tk.GroupType() { case TokenGroupMapKey: if len(tokens) <= i+1 { ret = append(ret, tk) continue } valueTk := tokens[i+1] if tk.Line() != valueTk.Line() { ret = append(ret, tk) continue } if valueTk.GroupType() == TokenGroupAnchorName { ret = append(ret, tk) continue } if valueTk.Type() == token.TagType && valueTk.GroupType() != TokenGroupScalarTag { ret = append(ret, tk) continue } if isScalarType(valueTk) || valueTk.Type() == token.TagType { ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupMapKeyValue, Tokens: []*Token{tk, valueTk}, }, }) i++ } else { ret = append(ret, tk) continue } default: ret = append(ret, tk) } } return ret } func createDirectiveTokenGroups(tokens []*Token) ([]*Token, error) { ret := make([]*Token, 0, len(tokens)) for i := 0; i < len(tokens); i++ { tk := tokens[i] switch tk.Type() { case token.DirectiveType: if i+1 >= len(tokens) { return nil, errors.ErrSyntax("undefined directive value", tk.RawToken()) } directiveName := &Token{ Group: &TokenGroup{ Type: TokenGroupDirectiveName, Tokens: []*Token{tk, tokens[i+1]}, }, } i++ var valueTks []*Token for j := i + 1; j < len(tokens); j++ { if tokens[j].Line() != tk.Line() { break } valueTks = append(valueTks, tokens[j]) i++ } if i+1 >= len(tokens) || tokens[i+1].Type() != token.DocumentHeaderType { return nil, errors.ErrSyntax("unexpected directive value. document not started", tk.RawToken()) } if len(valueTks) != 0 { ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupDirective, Tokens: append([]*Token{directiveName}, valueTks...), }, }) } else { ret = append(ret, directiveName) } default: ret = append(ret, tk) } } return ret, nil } func createDocumentTokens(tokens []*Token) ([]*Token, error) { var ret []*Token for i := 0; i < len(tokens); i++ { tk := tokens[i] switch tk.Type() { case token.DocumentHeaderType: if i != 0 { ret = append(ret, &Token{ Group: &TokenGroup{Tokens: tokens[:i]}, }) } if i+1 == len(tokens) { // if current token is last token, add DocumentHeader only tokens to ret. return append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupDocument, Tokens: []*Token{tk}, }, }), nil } if tokens[i+1].Type() == token.DocumentHeaderType { return append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupDocument, Tokens: []*Token{tk}, }, }), nil } if tokens[i].Line() == tokens[i+1].Line() { switch tokens[i+1].GroupType() { case TokenGroupMapKey, TokenGroupMapKeyValue: return nil, errors.ErrSyntax("value cannot be placed after document separator", tokens[i+1].RawToken()) } switch tokens[i+1].Type() { case token.SequenceEntryType: return nil, errors.ErrSyntax("value cannot be placed after document separator", tokens[i+1].RawToken()) } } tks, err := createDocumentTokens(tokens[i+1:]) if err != nil { return nil, err } if len(tks) != 0 { tks[0].SetGroupType(TokenGroupDocument) tks[0].Group.Tokens = append([]*Token{tk}, tks[0].Group.Tokens...) return append(ret, tks...), nil } return append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupDocument, Tokens: []*Token{tk}, }, }), nil case token.DocumentEndType: if i != 0 { ret = append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupDocument, Tokens: tokens[0 : i+1], }, }) } if i+1 == len(tokens) { return ret, nil } if isScalarType(tokens[i+1]) { return nil, errors.ErrSyntax("unexpected end content", tokens[i+1].RawToken()) } tks, err := createDocumentTokens(tokens[i+1:]) if err != nil { return nil, err } return append(ret, tks...), nil } } return append(ret, &Token{ Group: &TokenGroup{ Type: TokenGroupDocument, Tokens: tokens, }, }), nil } func isScalarType(tk *Token) bool { switch tk.GroupType() { case TokenGroupMapKey, TokenGroupMapKeyValue: return false } typ := tk.Type() return typ == token.AnchorType || typ == token.AliasType || typ == token.LiteralType || typ == token.FoldedType || typ == token.NullType || typ == token.ImplicitNullType || typ == token.BoolType || typ == token.IntegerType || typ == token.BinaryIntegerType || typ == token.OctetIntegerType || typ == token.HexIntegerType || typ == token.FloatType || typ == token.InfinityType || typ == token.NanType || typ == token.StringType || typ == token.SingleQuoteType || typ == token.DoubleQuoteType } func isNotMapKeyType(tk *Token) bool { typ := tk.Type() return typ == token.DirectiveType || typ == token.DocumentHeaderType || typ == token.DocumentEndType || typ == token.CollectEntryType || typ == token.MappingStartType || typ == token.MappingValueType || typ == token.MappingEndType || typ == token.SequenceStartType || typ == token.SequenceEntryType || typ == token.SequenceEndType } func isFlowType(tk *Token) bool { typ := tk.Type() return typ == token.MappingStartType || typ == token.MappingEndType || typ == token.SequenceStartType || typ == token.SequenceEntryType } goccy-go-yaml-52dacb8/path.go000066400000000000000000000475051501576637100161640ustar00rootroot00000000000000package yaml import ( "bytes" "fmt" "io" "strconv" "strings" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/parser" "github.com/goccy/go-yaml/printer" ) // PathString create Path from string // // YAMLPath rule // $ : the root object/element // . : child operator // .. : recursive descent // [num] : object/element of array by number // [*] : all objects/elements for array. // // If you want to use reserved characters such as `.` and `*` as a key name, // enclose them in single quotation as follows ( $.foo.'bar.baz-*'.hoge ). // If you want to use a single quote with reserved characters, escape it with `\` ( $.foo.'bar.baz\'s value'.hoge ). func PathString(s string) (*Path, error) { buf := []rune(s) length := len(buf) cursor := 0 builder := &PathBuilder{} for cursor < length { c := buf[cursor] switch c { case '$': builder = builder.Root() cursor++ case '.': b, buf, c, err := parsePathDot(builder, buf, cursor) if err != nil { return nil, err } length = len(buf) builder = b cursor = c case '[': b, buf, c, err := parsePathIndex(builder, buf, cursor) if err != nil { return nil, err } length = len(buf) builder = b cursor = c default: return nil, fmt.Errorf("invalid path at %d: %w", cursor, ErrInvalidPathString) } } return builder.Build(), nil } func parsePathRecursive(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) { length := len(buf) cursor += 2 // skip .. characters start := cursor for ; cursor < length; cursor++ { c := buf[cursor] switch c { case '$': return nil, nil, 0, fmt.Errorf("specified '$' after '..' character: %w", ErrInvalidPathString) case '*': return nil, nil, 0, fmt.Errorf("specified '*' after '..' character: %w", ErrInvalidPathString) case '.', '[': goto end case ']': return nil, nil, 0, fmt.Errorf("specified ']' after '..' character: %w", ErrInvalidPathString) } } end: if start == cursor { return nil, nil, 0, fmt.Errorf("not found recursive selector: %w", ErrInvalidPathString) } return b.Recursive(string(buf[start:cursor])), buf, cursor, nil } func parsePathDot(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) { if b.root == nil || b.node == nil { return nil, nil, 0, fmt.Errorf("required '$' character at first: %w", ErrInvalidPathString) } length := len(buf) if cursor+1 < length && buf[cursor+1] == '.' { b, buf, c, err := parsePathRecursive(b, buf, cursor) if err != nil { return nil, nil, 0, err } return b, buf, c, nil } cursor++ // skip . character start := cursor // if started single quote, looking for end single quote char if cursor < length && buf[cursor] == '\'' { return parseQuotedKey(b, buf, cursor) } for ; cursor < length; cursor++ { c := buf[cursor] switch c { case '$': return nil, nil, 0, fmt.Errorf("specified '$' after '.' character: %w", ErrInvalidPathString) case '*': return nil, nil, 0, fmt.Errorf("specified '*' after '.' character: %w", ErrInvalidPathString) case '.', '[': goto end case ']': return nil, nil, 0, fmt.Errorf("specified ']' after '.' character: %w", ErrInvalidPathString) } } end: if start == cursor { return nil, nil, 0, fmt.Errorf("could not find by empty key: %w", ErrInvalidPathString) } return b.child(string(buf[start:cursor])), buf, cursor, nil } func parseQuotedKey(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) { if b.root == nil || b.node == nil { return nil, nil, 0, fmt.Errorf("required '$' character at first: %w", ErrInvalidPathString) } cursor++ // skip single quote start := cursor length := len(buf) var foundEndDelim bool for ; cursor < length; cursor++ { switch buf[cursor] { case '\\': buf = append(append([]rune{}, buf[:cursor]...), buf[cursor+1:]...) length = len(buf) case '\'': foundEndDelim = true goto end } } end: if !foundEndDelim { return nil, nil, 0, fmt.Errorf("could not find end delimiter for key: %w", ErrInvalidPathString) } if start == cursor { return nil, nil, 0, fmt.Errorf("could not find by empty key: %w", ErrInvalidPathString) } selector := buf[start:cursor] cursor++ if cursor < length { switch buf[cursor] { case '$': return nil, nil, 0, fmt.Errorf("specified '$' after '.' character: %w", ErrInvalidPathString) case '*': return nil, nil, 0, fmt.Errorf("specified '*' after '.' character: %w", ErrInvalidPathString) case ']': return nil, nil, 0, fmt.Errorf("specified ']' after '.' character: %w", ErrInvalidPathString) } } return b.child(string(selector)), buf, cursor, nil } func parsePathIndex(b *PathBuilder, buf []rune, cursor int) (*PathBuilder, []rune, int, error) { if b.root == nil || b.node == nil { return nil, nil, 0, fmt.Errorf("required '$' character at first: %w", ErrInvalidPathString) } length := len(buf) cursor++ // skip '[' character if length <= cursor { return nil, nil, 0, fmt.Errorf("unexpected end of YAML Path: %w", ErrInvalidPathString) } c := buf[cursor] switch c { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*': start := cursor cursor++ for ; cursor < length; cursor++ { c := buf[cursor] switch c { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': continue } break } if buf[cursor] != ']' { return nil, nil, 0, fmt.Errorf("invalid character %s at %d: %w", string(buf[cursor]), cursor, ErrInvalidPathString) } numOrAll := string(buf[start:cursor]) if numOrAll == "*" { return b.IndexAll(), buf, cursor + 1, nil } num, err := strconv.ParseInt(numOrAll, 10, 64) if err != nil { return nil, nil, 0, err } return b.Index(uint(num)), buf, cursor + 1, nil } return nil, nil, 0, fmt.Errorf("invalid character %q at %d: %w", c, cursor, ErrInvalidPathString) } // Path represent YAMLPath ( like a JSONPath ). type Path struct { node pathNode } // String path to text. func (p *Path) String() string { return p.node.String() } // Read decode from r and set extracted value by YAMLPath to v. func (p *Path) Read(r io.Reader, v interface{}) error { node, err := p.ReadNode(r) if err != nil { return err } if err := Unmarshal([]byte(node.String()), v); err != nil { return err } return nil } // ReadNode create AST from r and extract node by YAMLPath. func (p *Path) ReadNode(r io.Reader) (ast.Node, error) { if p.node == nil { return nil, ErrInvalidPath } var buf bytes.Buffer if _, err := io.Copy(&buf, r); err != nil { return nil, err } f, err := parser.ParseBytes(buf.Bytes(), 0) if err != nil { return nil, err } node, err := p.FilterFile(f) if err != nil { return nil, err } return node, nil } // Filter filter from target by YAMLPath and set it to v. func (p *Path) Filter(target, v interface{}) error { b, err := Marshal(target) if err != nil { return err } if err := p.Read(bytes.NewBuffer(b), v); err != nil { return err } return nil } // FilterFile filter from ast.File by YAMLPath. func (p *Path) FilterFile(f *ast.File) (ast.Node, error) { for _, doc := range f.Docs { node, err := p.FilterNode(doc.Body) if err != nil { return nil, err } if node != nil { return node, nil } } return nil, fmt.Errorf("failed to find path ( %s ): %w", p.node, ErrNotFoundNode) } // FilterNode filter from node by YAMLPath. func (p *Path) FilterNode(node ast.Node) (ast.Node, error) { if node == nil { return nil, nil } n, err := p.node.filter(node) if err != nil { return nil, err } return n, nil } // MergeFromReader merge YAML text into ast.File. func (p *Path) MergeFromReader(dst *ast.File, src io.Reader) error { var buf bytes.Buffer if _, err := io.Copy(&buf, src); err != nil { return err } file, err := parser.ParseBytes(buf.Bytes(), 0) if err != nil { return err } if err := p.MergeFromFile(dst, file); err != nil { return err } return nil } // MergeFromFile merge ast.File into ast.File. func (p *Path) MergeFromFile(dst *ast.File, src *ast.File) error { base, err := p.FilterFile(dst) if err != nil { return err } for _, doc := range src.Docs { if err := ast.Merge(base, doc); err != nil { return err } } return nil } // MergeFromNode merge ast.Node into ast.File. func (p *Path) MergeFromNode(dst *ast.File, src ast.Node) error { base, err := p.FilterFile(dst) if err != nil { return err } if err := ast.Merge(base, src); err != nil { return err } return nil } // ReplaceWithReader replace ast.File with io.Reader. func (p *Path) ReplaceWithReader(dst *ast.File, src io.Reader) error { var buf bytes.Buffer if _, err := io.Copy(&buf, src); err != nil { return err } file, err := parser.ParseBytes(buf.Bytes(), 0) if err != nil { return err } if err := p.ReplaceWithFile(dst, file); err != nil { return err } return nil } // ReplaceWithFile replace ast.File with ast.File. func (p *Path) ReplaceWithFile(dst *ast.File, src *ast.File) error { for _, doc := range src.Docs { if err := p.ReplaceWithNode(dst, doc); err != nil { return err } } return nil } // ReplaceNode replace ast.File with ast.Node. func (p *Path) ReplaceWithNode(dst *ast.File, node ast.Node) error { for _, doc := range dst.Docs { if node.Type() == ast.DocumentType { node = node.(*ast.DocumentNode).Body } if err := p.node.replace(doc.Body, node); err != nil { return err } } return nil } // AnnotateSource add annotation to passed source ( see section 5.1 in README.md ). func (p *Path) AnnotateSource(source []byte, colored bool) ([]byte, error) { file, err := parser.ParseBytes([]byte(source), 0) if err != nil { return nil, err } node, err := p.FilterFile(file) if err != nil { return nil, err } var pp printer.Printer return []byte(pp.PrintErrorToken(node.GetToken(), colored)), nil } // PathBuilder represent builder for YAMLPath. type PathBuilder struct { root *rootNode node pathNode } // Root add '$' to current path. func (b *PathBuilder) Root() *PathBuilder { root := newRootNode() return &PathBuilder{root: root, node: root} } // IndexAll add '[*]' to current path. func (b *PathBuilder) IndexAll() *PathBuilder { b.node = b.node.chain(newIndexAllNode()) return b } // Recursive add '..selector' to current path. func (b *PathBuilder) Recursive(selector string) *PathBuilder { b.node = b.node.chain(newRecursiveNode(selector)) return b } func (b *PathBuilder) containsReservedPathCharacters(path string) bool { if strings.Contains(path, ".") { return true } if strings.Contains(path, "*") { return true } return false } func (b *PathBuilder) enclosedSingleQuote(name string) bool { return strings.HasPrefix(name, "'") && strings.HasSuffix(name, "'") } func (b *PathBuilder) normalizeSelectorName(name string) string { if b.enclosedSingleQuote(name) { // already escaped name return name } if b.containsReservedPathCharacters(name) { escapedName := strings.ReplaceAll(name, `'`, `\'`) return "'" + escapedName + "'" } return name } func (b *PathBuilder) child(name string) *PathBuilder { b.node = b.node.chain(newSelectorNode(name)) return b } // Child add '.name' to current path. func (b *PathBuilder) Child(name string) *PathBuilder { return b.child(b.normalizeSelectorName(name)) } // Index add '[idx]' to current path. func (b *PathBuilder) Index(idx uint) *PathBuilder { b.node = b.node.chain(newIndexNode(idx)) return b } // Build build YAMLPath. func (b *PathBuilder) Build() *Path { return &Path{node: b.root} } type pathNode interface { fmt.Stringer chain(pathNode) pathNode filter(ast.Node) (ast.Node, error) replace(ast.Node, ast.Node) error } type basePathNode struct { child pathNode } func (n *basePathNode) chain(node pathNode) pathNode { n.child = node return node } type rootNode struct { *basePathNode } func newRootNode() *rootNode { return &rootNode{basePathNode: &basePathNode{}} } func (n *rootNode) String() string { s := "$" if n.child != nil { s += n.child.String() } return s } func (n *rootNode) filter(node ast.Node) (ast.Node, error) { if n.child == nil { return node, nil } filtered, err := n.child.filter(node) if err != nil { return nil, err } return filtered, nil } func (n *rootNode) replace(node ast.Node, target ast.Node) error { if n.child == nil { return nil } if err := n.child.replace(node, target); err != nil { return err } return nil } type selectorNode struct { *basePathNode selector string } func newSelectorNode(selector string) *selectorNode { return &selectorNode{ basePathNode: &basePathNode{}, selector: selector, } } func (n *selectorNode) filter(node ast.Node) (ast.Node, error) { selector := n.selector if len(selector) > 1 && selector[0] == '\'' && selector[len(selector)-1] == '\'' { selector = selector[1 : len(selector)-1] } switch node.Type() { case ast.MappingType: for _, value := range node.(*ast.MappingNode).Values { key := value.Key.GetToken().Value if len(key) > 0 { switch key[0] { case '"': var err error key, err = strconv.Unquote(key) if err != nil { return nil, err } case '\'': if len(key) > 1 && key[len(key)-1] == '\'' { key = key[1 : len(key)-1] } } } if key == selector { if n.child == nil { return value.Value, nil } filtered, err := n.child.filter(value.Value) if err != nil { return nil, err } return filtered, nil } } case ast.MappingValueType: value, _ := node.(*ast.MappingValueNode) key := value.Key.GetToken().Value if key == selector { if n.child == nil { return value.Value, nil } filtered, err := n.child.filter(value.Value) if err != nil { return nil, err } return filtered, nil } default: return nil, fmt.Errorf("expected node type is map or map value. but got %s: %w", node.Type(), ErrInvalidQuery) } return nil, nil } func (n *selectorNode) replaceMapValue(value *ast.MappingValueNode, target ast.Node) error { key := value.Key.GetToken().Value if key != n.selector { return nil } if n.child == nil { if err := value.Replace(target); err != nil { return err } } else { if err := n.child.replace(value.Value, target); err != nil { return err } } return nil } func (n *selectorNode) replace(node ast.Node, target ast.Node) error { switch node.Type() { case ast.MappingType: for _, value := range node.(*ast.MappingNode).Values { if err := n.replaceMapValue(value, target); err != nil { return err } } case ast.MappingValueType: value, _ := node.(*ast.MappingValueNode) if err := n.replaceMapValue(value, target); err != nil { return err } default: return fmt.Errorf("expected node type is map or map value. but got %s: %w", node.Type(), ErrInvalidQuery) } return nil } func (n *selectorNode) String() string { var builder PathBuilder selector := builder.normalizeSelectorName(n.selector) s := fmt.Sprintf(".%s", selector) if n.child != nil { s += n.child.String() } return s } type indexNode struct { *basePathNode selector uint } func newIndexNode(selector uint) *indexNode { return &indexNode{ basePathNode: &basePathNode{}, selector: selector, } } func (n *indexNode) filter(node ast.Node) (ast.Node, error) { if node.Type() != ast.SequenceType { return nil, fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery) } sequence, _ := node.(*ast.SequenceNode) if n.selector >= uint(len(sequence.Values)) { return nil, fmt.Errorf("expected index is %d. but got sequences has %d items: %w", n.selector, len(sequence.Values), ErrInvalidQuery) } value := sequence.Values[n.selector] if n.child == nil { return value, nil } filtered, err := n.child.filter(value) if err != nil { return nil, err } return filtered, nil } func (n *indexNode) replace(node ast.Node, target ast.Node) error { if node.Type() != ast.SequenceType { return fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery) } sequence, _ := node.(*ast.SequenceNode) if n.selector >= uint(len(sequence.Values)) { return fmt.Errorf("expected index is %d. but got sequences has %d items: %w", n.selector, len(sequence.Values), ErrInvalidQuery) } if n.child == nil { if err := sequence.Replace(int(n.selector), target); err != nil { return err } return nil } if err := n.child.replace(sequence.Values[n.selector], target); err != nil { return err } return nil } func (n *indexNode) String() string { s := fmt.Sprintf("[%d]", n.selector) if n.child != nil { s += n.child.String() } return s } type indexAllNode struct { *basePathNode } func newIndexAllNode() *indexAllNode { return &indexAllNode{ basePathNode: &basePathNode{}, } } func (n *indexAllNode) String() string { s := "[*]" if n.child != nil { s += n.child.String() } return s } func (n *indexAllNode) filter(node ast.Node) (ast.Node, error) { if node.Type() != ast.SequenceType { return nil, fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery) } sequence, _ := node.(*ast.SequenceNode) if n.child == nil { return sequence, nil } out := *sequence out.Values = []ast.Node{} for _, value := range sequence.Values { filtered, err := n.child.filter(value) if err != nil { return nil, err } out.Values = append(out.Values, filtered) } return &out, nil } func (n *indexAllNode) replace(node ast.Node, target ast.Node) error { if node.Type() != ast.SequenceType { return fmt.Errorf("expected sequence type node. but got %s: %w", node.Type(), ErrInvalidQuery) } sequence, _ := node.(*ast.SequenceNode) if n.child == nil { for idx := range sequence.Values { if err := sequence.Replace(idx, target); err != nil { return err } } return nil } for _, value := range sequence.Values { if err := n.child.replace(value, target); err != nil { return err } } return nil } type recursiveNode struct { *basePathNode selector string } func newRecursiveNode(selector string) *recursiveNode { return &recursiveNode{ basePathNode: &basePathNode{}, selector: selector, } } func (n *recursiveNode) String() string { s := fmt.Sprintf("..%s", n.selector) if n.child != nil { s += n.child.String() } return s } func (n *recursiveNode) filterNode(node ast.Node) (*ast.SequenceNode, error) { sequence := &ast.SequenceNode{BaseNode: &ast.BaseNode{}} switch typedNode := node.(type) { case *ast.MappingNode: for _, value := range typedNode.Values { seq, err := n.filterNode(value) if err != nil { return nil, err } sequence.Values = append(sequence.Values, seq.Values...) } case *ast.MappingValueNode: key := typedNode.Key.GetToken().Value if n.selector == key { sequence.Values = append(sequence.Values, typedNode.Value) } seq, err := n.filterNode(typedNode.Value) if err != nil { return nil, err } sequence.Values = append(sequence.Values, seq.Values...) case *ast.SequenceNode: for _, value := range typedNode.Values { seq, err := n.filterNode(value) if err != nil { return nil, err } sequence.Values = append(sequence.Values, seq.Values...) } } return sequence, nil } func (n *recursiveNode) filter(node ast.Node) (ast.Node, error) { sequence, err := n.filterNode(node) if err != nil { return nil, err } sequence.Start = node.GetToken() return sequence, nil } func (n *recursiveNode) replaceNode(node ast.Node, target ast.Node) error { switch typedNode := node.(type) { case *ast.MappingNode: for _, value := range typedNode.Values { if err := n.replaceNode(value, target); err != nil { return err } } case *ast.MappingValueNode: key := typedNode.Key.GetToken().Value if n.selector == key { if err := typedNode.Replace(target); err != nil { return err } } if err := n.replaceNode(typedNode.Value, target); err != nil { return err } case *ast.SequenceNode: for _, value := range typedNode.Values { if err := n.replaceNode(value, target); err != nil { return err } } } return nil } func (n *recursiveNode) replace(node ast.Node, target ast.Node) error { if err := n.replaceNode(node, target); err != nil { return err } return nil } goccy-go-yaml-52dacb8/path_test.go000066400000000000000000000412021501576637100172070ustar00rootroot00000000000000package yaml_test import ( "fmt" "log" "reflect" "strings" "testing" "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/parser" ) func builder() *yaml.PathBuilder { return &yaml.PathBuilder{} } func TestPathBuilder(t *testing.T) { tests := []struct { expected string path *yaml.Path }{ { expected: `$.a.b[0]`, path: builder().Root().Child("a").Child("b").Index(0).Build(), }, { expected: `$.'a.b'.'c*d'`, path: builder().Root().Child("a.b").Child("c*d").Build(), }, { expected: `$.'a.b-*'.c`, path: builder().Root().Child("a.b-*").Child("c").Build(), }, { expected: `$.'a'.b`, path: builder().Root().Child("'a'").Child("b").Build(), }, { expected: `$.'a.b'.c`, path: builder().Root().Child("'a.b'").Child("c").Build(), }, } for _, test := range tests { t.Run(test.expected, func(t *testing.T) { expected := test.expected got := test.path.String() if expected != got { t.Fatalf("failed to build path. expected:[%q] but got:[%q]", expected, got) } }) } } func TestPath(t *testing.T) { yml := ` store: book: - author: john price: 10 - author: ken price: 12 bicycle: color: red price: 19.95 bicycle*unicycle: price: 20.25 ` tests := []struct { name string path *yaml.Path expected interface{} }{ { name: "$.store.book[0].author", path: builder().Root().Child("store").Child("book").Index(0).Child("author").Build(), expected: "john", }, { name: "$.store.book[1].price", path: builder().Root().Child("store").Child("book").Index(1).Child("price").Build(), expected: uint64(12), }, { name: "$.store.book[*].author", path: builder().Root().Child("store").Child("book").IndexAll().Child("author").Build(), expected: []interface{}{"john", "ken"}, }, { name: "$.store.book[*]", path: builder().Root().Child("store").Child("book").IndexAll().Build(), expected: []interface{}{ map[string]interface{}{ "author": "john", "price": uint64(10), }, map[string]interface{}{ "author": "ken", "price": uint64(12), }, }, }, { name: "$..book[*]", path: builder().Root().Recursive("book").IndexAll().Build(), expected: []interface{}{ []interface{}{ map[string]interface{}{ "author": "john", "price": uint64(10), }, map[string]interface{}{ "author": "ken", "price": uint64(12), }, }, }, }, { name: "$.store.book[0]", path: builder().Root().Child("store").Child("book").Index(0).Build(), expected: map[string]interface{}{"author": "john", "price": uint64(10)}, }, { name: "$..author", path: builder().Root().Recursive("author").Build(), expected: []interface{}{"john", "ken"}, }, { name: "$.store.bicycle.price", path: builder().Root().Child("store").Child("bicycle").Child("price").Build(), expected: float64(19.95), }, { name: `$.store.'bicycle*unicycle'.price`, path: builder().Root().Child("store").Child(`bicycle*unicycle`).Child("price").Build(), expected: float64(20.25), }, { name: "$", path: builder().Root().Build(), expected: map[string]interface{}{ "store": map[string]interface{}{ "book": []interface{}{ map[string]interface{}{ "author": "john", "price": uint64(10), }, map[string]interface{}{ "author": "ken", "price": uint64(12), }, }, "bicycle": map[string]interface{}{ "color": "red", "price": 19.95, }, "bicycle*unicycle": map[string]interface{}{ "price": 20.25, }, }, }, }, } t.Run("PathString", func(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { path, err := yaml.PathString(test.name) if err != nil { t.Fatalf("%+v", err) } if test.name != path.String() { t.Fatalf("expected %s but actual %s", test.name, path.String()) } }) } }) t.Run("string", func(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { if test.name != test.path.String() { t.Fatalf("expected %s but actual %s", test.name, test.path.String()) } }) } }) t.Run("read", func(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { var v interface{} if err := test.path.Read(strings.NewReader(yml), &v); err != nil { t.Fatalf("%+v", err) } if !reflect.DeepEqual(test.expected, v) { t.Fatalf("expected %v(%T). but actual %v(%T)", test.expected, test.expected, v, v) } }) } }) t.Run("filter", func(t *testing.T) { var target interface{} if err := yaml.Unmarshal([]byte(yml), &target); err != nil { t.Fatalf("failed to unmarshal: %+v", err) } for _, test := range tests { t.Run(test.name, func(t *testing.T) { var v interface{} if err := test.path.Filter(target, &v); err != nil { t.Fatalf("%+v", err) } if !reflect.DeepEqual(test.expected, v) { t.Fatalf("expected %v(%T). but actual %v(%T)", test.expected, test.expected, v, v) } }) } }) } func TestPath_ReservedKeyword(t *testing.T) { tests := []struct { name string path string src string expected interface{} failure bool }{ { name: "quoted path", path: `$.'a.b.c'.foo`, src: ` a.b.c: foo: bar `, expected: "bar", }, { name: "contains quote key", path: `$.a'b`, src: `a'b: 10`, expected: uint64(10), }, { name: "escaped quote", path: `$.'alice\'s age'`, src: `alice's age: 10`, expected: uint64(10), }, { name: "directly use white space", path: `$.a b`, src: `a b: 10`, expected: uint64(10), }, { name: "empty quoted key", path: `$.''`, src: `a: 10`, failure: true, }, { name: "unterminated quote", path: `$.'abcd`, src: `abcd: 10`, failure: true, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { path, err := yaml.PathString(test.path) if test.failure { if err == nil { t.Fatal("expected error") } return } else { if err != nil { t.Fatalf("%+v", err) } } file, err := parser.ParseBytes([]byte(test.src), 0) if err != nil { t.Fatal(err) } var v interface{} if err := path.Read(file, &v); err != nil { t.Fatalf("%+v", err) } if v != test.expected { t.Fatalf("failed to get value. expected:[%v] but got:[%v]", test.expected, v) } }) } } func TestPath_Invalid(t *testing.T) { tests := []struct { path string src string }{ { path: "$.wrong", src: "foo: bar", }, } for _, test := range tests { path, err := yaml.PathString(test.path) if err != nil { t.Fatal(err) } t.Run("path.Read", func(t *testing.T) { file, err := parser.ParseBytes([]byte(test.src), 0) if err != nil { t.Fatal(err) } var v interface{} err = path.Read(file, &v) if err == nil { t.Fatal("expected error") } if !yaml.IsNotFoundNodeError(err) { t.Fatalf("unexpected error %s", err) } }) t.Run("path.ReadNode", func(t *testing.T) { file, err := parser.ParseBytes([]byte(test.src), 0) if err != nil { t.Fatal(err) } _, err = path.ReadNode(file) if err == nil { t.Fatal("expected error") } if !yaml.IsNotFoundNodeError(err) { t.Fatalf("unexpected error %s", err) } }) } } func TestPath_ReadNode(t *testing.T) { tests := []struct { name string path string src string expected interface{} }{ { name: "nested array sequence", path: `$.a.b[0].c`, src: ` a: b: - c: 123 e: | Line1 Line2 `, expected: uint64(123), }, { name: "nested array sequence issue#281", path: `$..a.c`, src: ` s: - a: b: u1 c: get1 d: i1 - w: c: bad e: - a: b: u2 c: get2 d: i2 `, // The expected values are // - get1 // - get2 expected: []interface{}{ map[string]interface{}{ "b": "u1", "c": "get1", "d": "i1", }, map[string]interface{}{ "b": "u2", "c": "get2", "d": "i2", }, }, }, { name: "nested array sequence issue#281", path: `$..c`, src: ` s: - a: b: u1 c: get1 d: i1 - w: c: bad e: - a: b: u2 c: get2 d: i2 `, expected: []interface{}{"get1", "bad", "get2"}, }, { name: "nested array sequence issue#281", path: `$.s[0].a.c`, src: ` s: - a: b: u1 c: get1 d: i1 - w: c: bad e: - a: b: u2 c: get2 d: i2 `, expected: "get1", }, { name: "nested array sequence issue#281", path: "$.s[*].a.c", src: ` s: - a: b: u1 c: get1 d: i1 - w: c: bad e: - a: b: u2 c: get2 d: i2 `, expected: []interface{}{"get1"}, }, } for _, test := range tests { path, err := yaml.PathString(test.path) if err != nil { t.Fatal(err) } t.Run(fmt.Sprintf("path.ReadNode %s path %s", test.name, test.path), func(t *testing.T) { file, err := parser.ParseBytes([]byte(test.src), 0) if err != nil { t.Fatal(err) } n, err := path.ReadNode(file) if err != nil { t.Fatal("expected error", err) } var v interface{} err = yaml.Unmarshal([]byte(n.String()), &v) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(test.expected, v) { t.Fatalf("expected %v(%T) but got %v(%T)", test.expected, test.expected, v, v) } }) } } func TestPath_Merge(t *testing.T) { tests := []struct { path string dst string src string expected string }{ { path: "$.c", dst: ` a: 1 b: 2 c: d: 3 e: 4 `, src: ` f: 5 g: 6 `, expected: ` a: 1 b: 2 c: d: 3 e: 4 f: 5 g: 6 `, }, { path: "$.a.b", dst: ` a: b: - 1 - 2 `, src: ` - 3 - map: - 4 - 5 `, expected: ` a: b: - 1 - 2 - 3 - map: - 4 - 5 `, }, } for _, test := range tests { t.Run(test.path, func(t *testing.T) { path, err := yaml.PathString(test.path) if err != nil { t.Fatalf("%+v", err) } t.Run("FromReader", func(t *testing.T) { file, err := parser.ParseBytes([]byte(test.dst), 0) if err != nil { t.Fatalf("%+v", err) } if err := path.MergeFromReader(file, strings.NewReader(test.src)); err != nil { t.Fatalf("%+v", err) } actual := "\n" + file.String() if test.expected != actual { t.Fatalf("expected: %q. but got %q", test.expected, actual) } }) t.Run("FromFile", func(t *testing.T) { file, err := parser.ParseBytes([]byte(test.dst), 0) if err != nil { t.Fatalf("%+v", err) } src, err := parser.ParseBytes([]byte(test.src), 0) if err != nil { t.Fatalf("%+v", err) } if err := path.MergeFromFile(file, src); err != nil { t.Fatalf("%+v", err) } actual := "\n" + file.String() if test.expected != actual { t.Fatalf("expected: %q. but got %q", test.expected, actual) } }) t.Run("FromNode", func(t *testing.T) { file, err := parser.ParseBytes([]byte(test.dst), 0) if err != nil { t.Fatalf("%+v", err) } src, err := parser.ParseBytes([]byte(test.src), 0) if err != nil { t.Fatalf("%+v", err) } if len(src.Docs) == 0 { t.Fatalf("failed to parse") } if err := path.MergeFromNode(file, src.Docs[0]); err != nil { t.Fatalf("%+v", err) } actual := "\n" + file.String() if test.expected != actual { t.Fatalf("expected: %q. but got %q", test.expected, actual) } }) }) } } func TestPath_Replace(t *testing.T) { tests := []struct { path string dst string src string expected string }{ { path: "$.a", dst: ` a: 1 b: 2 `, src: `3`, expected: ` a: 3 b: 2 `, }, { path: "$.b", dst: ` b: 1 c: 2 `, src: ` d: e f: g: h i: j `, expected: ` b: d: e f: g: h i: j c: 2 `, }, { path: "$.a.b[0]", dst: ` a: b: - hello c: 2 `, src: `world`, expected: ` a: b: - world c: 2 `, }, { path: "$.books[*].author", dst: ` books: - name: book_a author: none - name: book_b author: none pictures: - name: picture_a author: none - name: picture_b author: none building: author: none `, src: `ken`, expected: ` books: - name: book_a author: ken - name: book_b author: ken pictures: - name: picture_a author: none - name: picture_b author: none building: author: none `, }, { path: "$..author", dst: ` books: - name: book_a author: none - name: book_b author: none pictures: - name: picture_a author: none - name: picture_b author: none building: author: none `, src: `ken`, expected: ` books: - name: book_a author: ken - name: book_b author: ken pictures: - name: picture_a author: ken - name: picture_b author: ken building: author: ken `, }, } for _, test := range tests { t.Run(test.path, func(t *testing.T) { path, err := yaml.PathString(test.path) if err != nil { t.Fatalf("%+v", err) } t.Run("WithReader", func(t *testing.T) { file, err := parser.ParseBytes([]byte(test.dst), 0) if err != nil { t.Fatalf("%+v", err) } if err := path.ReplaceWithReader(file, strings.NewReader(test.src)); err != nil { t.Fatalf("%+v", err) } actual := "\n" + file.String() if test.expected != actual { t.Fatalf("expected: %q. but got %q", test.expected, actual) } }) t.Run("WithFile", func(t *testing.T) { file, err := parser.ParseBytes([]byte(test.dst), 0) if err != nil { t.Fatalf("%+v", err) } src, err := parser.ParseBytes([]byte(test.src), 0) if err != nil { t.Fatalf("%+v", err) } if err := path.ReplaceWithFile(file, src); err != nil { t.Fatalf("%+v", err) } actual := "\n" + file.String() if test.expected != actual { t.Fatalf("expected: %q. but got %q", test.expected, actual) } }) t.Run("WithNode", func(t *testing.T) { file, err := parser.ParseBytes([]byte(test.dst), 0) if err != nil { t.Fatalf("%+v", err) } src, err := parser.ParseBytes([]byte(test.src), 0) if err != nil { t.Fatalf("%+v", err) } if len(src.Docs) == 0 { t.Fatalf("failed to parse") } if err := path.ReplaceWithNode(file, src.Docs[0]); err != nil { t.Fatalf("%+v", err) } actual := "\n" + file.String() if test.expected != actual { t.Fatalf("expected: %q. but got %q", test.expected, actual) } }) }) } } func TestInvalidPath(t *testing.T) { tests := []struct { name string path string }{ { name: "missing root with dot", path: ".foo", }, { name: "missing root with index", path: "foo[0]", }, { name: "missing root with recursive", path: "..foo", }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { if _, err := yaml.PathString(test.path); err == nil { t.Fatal("expected error") } }) } } func ExamplePath_AnnotateSource() { yml := ` a: 1 b: "hello" ` var v struct { A int B string } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { panic(err) } if v.A != 2 { // output error with YAML source path, err := yaml.PathString("$.a") if err != nil { log.Fatal(err) } source, err := path.AnnotateSource([]byte(yml), false) if err != nil { log.Fatal(err) } fmt.Printf("a value expected 2 but actual %d:\n%s\n", v.A, string(source)) } // OUTPUT: // a value expected 2 but actual 1: // > 2 | a: 1 // ^ // 3 | b: "hello" } func ExamplePath_AnnotateSource_withComment() { yml := ` # This is my document doc: # This comment should be line 3 map: # And below should be line 5 - value1 - value2 other: value3 ` path, err := yaml.PathString("$.doc.map[0]") if err != nil { log.Fatal(err) } msg, err := path.AnnotateSource([]byte(yml), false) if err != nil { log.Fatal(err) } fmt.Println(string(msg)) // OUTPUT: // 4 | # This comment should be line 3 // 5 | map: // 6 | # And below should be line 5 // > 7 | - value1 // ^ // 8 | - value2 // 9 | other: value3 } func ExamplePathString() { yml := ` store: book: - author: john price: 10 - author: ken price: 12 bicycle: color: red price: 19.95 ` path, err := yaml.PathString("$.store.book[*].author") if err != nil { log.Fatal(err) } var authors []string if err := path.Read(strings.NewReader(yml), &authors); err != nil { log.Fatal(err) } fmt.Println(authors) // OUTPUT: // [john ken] } goccy-go-yaml-52dacb8/printer/000077500000000000000000000000001501576637100163515ustar00rootroot00000000000000goccy-go-yaml-52dacb8/printer/color.go000066400000000000000000000033441501576637100200220ustar00rootroot00000000000000// This source inspired by https://github.com/fatih/color. package printer import ( "fmt" "strings" ) type ColorAttribute int const ( ColorReset ColorAttribute = iota ColorBold ColorFaint ColorItalic ColorUnderline ColorBlinkSlow ColorBlinkRapid ColorReverseVideo ColorConcealed ColorCrossedOut ) const ( ColorFgHiBlack ColorAttribute = iota + 90 ColorFgHiRed ColorFgHiGreen ColorFgHiYellow ColorFgHiBlue ColorFgHiMagenta ColorFgHiCyan ColorFgHiWhite ) const ( ColorResetBold ColorAttribute = iota + 22 ColorResetItalic ColorResetUnderline ColorResetBlinking ColorResetReversed ColorResetConcealed ColorResetCrossedOut ) const escape = "\x1b" var colorResetMap = map[ColorAttribute]ColorAttribute{ ColorBold: ColorResetBold, ColorFaint: ColorResetBold, ColorItalic: ColorResetItalic, ColorUnderline: ColorResetUnderline, ColorBlinkSlow: ColorResetBlinking, ColorBlinkRapid: ColorResetBlinking, ColorReverseVideo: ColorResetReversed, ColorConcealed: ColorResetConcealed, ColorCrossedOut: ColorResetCrossedOut, } func format(attrs ...ColorAttribute) string { format := make([]string, 0, len(attrs)) for _, attr := range attrs { format = append(format, fmt.Sprint(attr)) } return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";")) } func unformat(attrs ...ColorAttribute) string { format := make([]string, len(attrs)) for _, attr := range attrs { v := fmt.Sprint(ColorReset) reset, exists := colorResetMap[attr] if exists { v = fmt.Sprint(reset) } format = append(format, v) } return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";")) } func colorize(msg string, attrs ...ColorAttribute) string { return format(attrs...) + msg + unformat(attrs...) } goccy-go-yaml-52dacb8/printer/printer.go000066400000000000000000000176701501576637100203760ustar00rootroot00000000000000package printer import ( "fmt" "math" "strings" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/token" ) // Property additional property set for each the token type Property struct { Prefix string Suffix string } // PrintFunc returns property instance type PrintFunc func() *Property // Printer create text from token collection or ast type Printer struct { LineNumber bool LineNumberFormat func(num int) string MapKey PrintFunc Anchor PrintFunc Alias PrintFunc Bool PrintFunc String PrintFunc Number PrintFunc Comment PrintFunc } func defaultLineNumberFormat(num int) string { return fmt.Sprintf("%2d | ", num) } func (p *Printer) property(tk *token.Token) *Property { prop := &Property{} switch tk.PreviousType() { case token.AnchorType: if p.Anchor != nil { return p.Anchor() } return prop case token.AliasType: if p.Alias != nil { return p.Alias() } return prop } switch tk.NextType() { case token.MappingValueType: if p.MapKey != nil { return p.MapKey() } return prop } switch tk.Type { case token.BoolType: if p.Bool != nil { return p.Bool() } return prop case token.AnchorType: if p.Anchor != nil { return p.Anchor() } return prop case token.AliasType: if p.Anchor != nil { return p.Alias() } return prop case token.StringType, token.SingleQuoteType, token.DoubleQuoteType: if p.String != nil { return p.String() } return prop case token.IntegerType, token.FloatType: if p.Number != nil { return p.Number() } return prop case token.CommentType: if p.Comment != nil { return p.Comment() } return prop default: } return prop } // PrintTokens create text from token collection func (p *Printer) PrintTokens(tokens token.Tokens) string { if len(tokens) == 0 { return "" } if p.LineNumber { if p.LineNumberFormat == nil { p.LineNumberFormat = defaultLineNumberFormat } } texts := []string{} lineNumber := tokens[0].Position.Line for _, tk := range tokens { lines := strings.Split(tk.Origin, "\n") prop := p.property(tk) header := "" if p.LineNumber { header = p.LineNumberFormat(lineNumber) } if len(lines) == 1 { line := prop.Prefix + lines[0] + prop.Suffix if len(texts) == 0 { texts = append(texts, header+line) lineNumber++ } else { text := texts[len(texts)-1] texts[len(texts)-1] = text + line } } else { for idx, src := range lines { if p.LineNumber { header = p.LineNumberFormat(lineNumber) } line := prop.Prefix + src + prop.Suffix if idx == 0 { if len(texts) == 0 { texts = append(texts, header+line) lineNumber++ } else { text := texts[len(texts)-1] texts[len(texts)-1] = text + line } } else { texts = append(texts, fmt.Sprintf("%s%s", header, line)) lineNumber++ } } } } return strings.Join(texts, "\n") } // PrintNode create text from ast.Node func (p *Printer) PrintNode(node ast.Node) []byte { return []byte(fmt.Sprintf("%+v\n", node)) } func (p *Printer) setDefaultColorSet() { p.Bool = func() *Property { return &Property{ Prefix: format(ColorFgHiMagenta), Suffix: format(ColorReset), } } p.Number = func() *Property { return &Property{ Prefix: format(ColorFgHiMagenta), Suffix: format(ColorReset), } } p.MapKey = func() *Property { return &Property{ Prefix: format(ColorFgHiCyan), Suffix: format(ColorReset), } } p.Anchor = func() *Property { return &Property{ Prefix: format(ColorFgHiYellow), Suffix: format(ColorReset), } } p.Alias = func() *Property { return &Property{ Prefix: format(ColorFgHiYellow), Suffix: format(ColorReset), } } p.String = func() *Property { return &Property{ Prefix: format(ColorFgHiGreen), Suffix: format(ColorReset), } } p.Comment = func() *Property { return &Property{ Prefix: format(ColorFgHiBlack), Suffix: format(ColorReset), } } } func (p *Printer) PrintErrorMessage(msg string, isColored bool) string { if isColored { return fmt.Sprintf("%s%s%s", format(ColorFgHiRed), msg, format(ColorReset), ) } return msg } func (p *Printer) removeLeftSideNewLineChar(src string) string { return strings.TrimLeft(strings.TrimLeft(strings.TrimLeft(src, "\r"), "\n"), "\r\n") } func (p *Printer) removeRightSideNewLineChar(src string) string { return strings.TrimRight(strings.TrimRight(strings.TrimRight(src, "\r"), "\n"), "\r\n") } func (p *Printer) removeRightSideWhiteSpaceChar(src string) string { return p.removeRightSideNewLineChar(strings.TrimRight(src, " ")) } func (p *Printer) newLineCount(s string) int { src := []rune(s) size := len(src) cnt := 0 for i := 0; i < size; i++ { c := src[i] switch c { case '\r': if i+1 < size && src[i+1] == '\n' { i++ } cnt++ case '\n': cnt++ } } return cnt } func (p *Printer) isNewLineLastChar(s string) bool { for i := len(s) - 1; i > 0; i-- { c := s[i] switch c { case ' ': continue case '\n', '\r': return true } break } return false } func (p *Printer) printBeforeTokens(tk *token.Token, minLine, extLine int) token.Tokens { for tk.Prev != nil { if tk.Prev.Position.Line < minLine { break } tk = tk.Prev } minTk := tk.Clone() if minTk.Prev != nil { // add white spaces to minTk by prev token prev := minTk.Prev whiteSpaceLen := len(prev.Origin) - len(strings.TrimRight(prev.Origin, " ")) minTk.Origin = strings.Repeat(" ", whiteSpaceLen) + minTk.Origin } minTk.Origin = p.removeLeftSideNewLineChar(minTk.Origin) tokens := token.Tokens{minTk} tk = minTk.Next for tk != nil && tk.Position.Line <= extLine { clonedTk := tk.Clone() tokens.Add(clonedTk) tk = clonedTk.Next } lastTk := tokens[len(tokens)-1] trimmedOrigin := p.removeRightSideWhiteSpaceChar(lastTk.Origin) suffix := lastTk.Origin[len(trimmedOrigin):] lastTk.Origin = trimmedOrigin if lastTk.Next != nil && len(suffix) > 1 { next := lastTk.Next.Clone() // add suffix to header of next token if suffix[0] == '\n' || suffix[0] == '\r' { suffix = suffix[1:] } next.Origin = suffix + next.Origin lastTk.Next = next } return tokens } func (p *Printer) printAfterTokens(tk *token.Token, maxLine int) token.Tokens { tokens := token.Tokens{} if tk == nil { return tokens } if tk.Position.Line > maxLine { return tokens } minTk := tk.Clone() minTk.Origin = p.removeLeftSideNewLineChar(minTk.Origin) tokens.Add(minTk) tk = minTk.Next for tk != nil && tk.Position.Line <= maxLine { clonedTk := tk.Clone() tokens.Add(clonedTk) tk = clonedTk.Next } return tokens } func (p *Printer) setupErrorTokenFormat(annotateLine int, isColored bool) { prefix := func(annotateLine, num int) string { if annotateLine == num { return fmt.Sprintf("> %2d | ", num) } return fmt.Sprintf(" %2d | ", num) } p.LineNumber = true p.LineNumberFormat = func(num int) string { if isColored { return colorize(prefix(annotateLine, num), ColorBold, ColorFgHiWhite) } return prefix(annotateLine, num) } if isColored { p.setDefaultColorSet() } } func (p *Printer) PrintErrorToken(tk *token.Token, isColored bool) string { errToken := tk curLine := tk.Position.Line curExtLine := curLine + p.newLineCount(p.removeLeftSideNewLineChar(tk.Origin)) if p.isNewLineLastChar(tk.Origin) { // if last character ( exclude white space ) is new line character, ignore it. curExtLine-- } minLine := int(math.Max(float64(curLine-3), 1)) maxLine := curExtLine + 3 p.setupErrorTokenFormat(curLine, isColored) beforeTokens := p.printBeforeTokens(tk, minLine, curExtLine) lastTk := beforeTokens[len(beforeTokens)-1] afterTokens := p.printAfterTokens(lastTk.Next, maxLine) beforeSource := p.PrintTokens(beforeTokens) prefixSpaceNum := len(fmt.Sprintf(" %2d | ", curLine)) annotateLine := strings.Repeat(" ", prefixSpaceNum+errToken.Position.Column-1) + "^" afterSource := p.PrintTokens(afterTokens) return fmt.Sprintf("%s\n%s\n%s", beforeSource, annotateLine, afterSource) } goccy-go-yaml-52dacb8/printer/printer_test.go000066400000000000000000000101361501576637100214230ustar00rootroot00000000000000package printer_test import ( "fmt" "testing" "github.com/goccy/go-yaml/lexer" "github.com/goccy/go-yaml/printer" ) func Test_Printer(t *testing.T) { yml := `--- text: aaaa text2: aaaa bbbb cccc dddd eeee text3: ffff gggg hhhh iiii jjjj bool: true number: 10 anchor: &x 1 alias: *x ` t.Run("print starting from tokens[3]", func(t *testing.T) { tokens := lexer.Tokenize(yml) var p printer.Printer actual := "\n" + p.PrintErrorToken(tokens[3], false) expect := ` 1 | --- > 2 | text: aaaa ^ 3 | text2: aaaa 4 | bbbb 5 | cccc 6 | dddd 7 | eeee 8 | ` if actual != expect { t.Fatalf("unexpected output: expect:[%s]\n actual:[%s]", expect, actual) } }) t.Run("print starting from tokens[4]", func(t *testing.T) { tokens := lexer.Tokenize(yml) var p printer.Printer actual := "\n" + p.PrintErrorToken(tokens[4], false) expect := ` 1 | --- 2 | text: aaaa > 3 | text2: aaaa 4 | bbbb 5 | cccc 6 | dddd 7 | eeee ^ ` if actual != expect { t.Fatalf("unexpected output: expect:[%s]\n actual:[%s]", expect, actual) } }) t.Run("print starting from tokens[6]", func(t *testing.T) { tokens := lexer.Tokenize(yml) var p printer.Printer actual := "\n" + p.PrintErrorToken(tokens[6], false) expect := ` 1 | --- 2 | text: aaaa > 3 | text2: aaaa 4 | bbbb 5 | cccc 6 | dddd 7 | eeee ^ 8 | text3: ffff 9 | gggg 10 | hhhh 11 | iiii 12 | jjjj 13 | ` if actual != expect { t.Fatalf("unexpected output: expect:[%s]\n actual:[%s]", expect, actual) } }) t.Run("print error token with document header", func(t *testing.T) { tokens := lexer.Tokenize(`--- a: b: c: d: e f: g h: i --- `) expect := ` 3 | b: 4 | c: 5 | d: e > 6 | f: g ^ 7 | h: i 8 | 9 | ---` var p printer.Printer actual := "\n" + p.PrintErrorToken(tokens[12], false) if actual != expect { t.Fatalf("unexpected output: expect:[%s]\n actual:[%s]", expect, actual) } }) t.Run("output with color", func(t *testing.T) { t.Run("token6", func(t *testing.T) { tokens := lexer.Tokenize(yml) var p printer.Printer t.Logf("\n%s", p.PrintErrorToken(tokens[6], true)) }) t.Run("token9", func(t *testing.T) { tokens := lexer.Tokenize(yml) var p printer.Printer t.Logf("\n%s", p.PrintErrorToken(tokens[9], true)) }) t.Run("token12", func(t *testing.T) { tokens := lexer.Tokenize(yml) var p printer.Printer t.Logf("\n%s", p.PrintErrorToken(tokens[12], true)) }) }) t.Run("print error message", func(t *testing.T) { var p printer.Printer src := "message" msg := p.PrintErrorMessage(src, false) if msg != src { t.Fatal("unexpected result") } p.PrintErrorMessage(src, true) }) } func TestPrinter_Anchor(t *testing.T) { expected := ` anchor: &x 1 alias: *x` tokens := lexer.Tokenize(expected) var p printer.Printer got := p.PrintTokens(tokens) if expected != got { t.Fatalf("unexpected output: expect:[%s]\n actual:[%s]", expected, got) } } func Test_Printer_Multiline(t *testing.T) { yml := ` text1: 'aaaa bbbb cccc' text2: "ffff gggg hhhh" text3: hello ` tc := []struct { token int want string }{ { token: 2, want: ` > 2 | text1: 'aaaa 3 | bbbb 4 | cccc' ^ 5 | text2: "ffff 6 | gggg 7 | hhhh"`, }, {token: 3, want: ` 2 | text1: 'aaaa 3 | bbbb 4 | cccc' > 5 | text2: "ffff 6 | gggg 7 | hhhh" ^ 8 | text3: hello`, }, {token: 5, want: ` 2 | text1: 'aaaa 3 | bbbb 4 | cccc' > 5 | text2: "ffff 6 | gggg 7 | hhhh" ^ 8 | text3: hello`, }, {token: 6, want: ` 5 | text2: "ffff 6 | gggg 7 | hhhh" > 8 | text3: hello ^ `, }, } for _, tt := range tc { name := fmt.Sprintf("print starting from tokens[%d]", tt.token) t.Run(name, func(t *testing.T) { tokens := lexer.Tokenize(yml) var p printer.Printer got := "\n" + p.PrintErrorToken(tokens[tt.token], false) want := tt.want if got != want { t.Fatalf("PrintErrorToken() got: %s\n want:%s\n", want, got) } }) } } goccy-go-yaml-52dacb8/scanner/000077500000000000000000000000001501576637100163175ustar00rootroot00000000000000goccy-go-yaml-52dacb8/scanner/context.go000066400000000000000000000234131501576637100203350ustar00rootroot00000000000000package scanner import ( "errors" "strconv" "strings" "sync" "github.com/goccy/go-yaml/token" ) // Context context at scanning type Context struct { idx int size int notSpaceCharPos int notSpaceOrgCharPos int src []rune buf []rune obuf []rune tokens token.Tokens mstate *MultiLineState } type MultiLineState struct { opt string firstLineIndentColumn int prevLineIndentColumn int lineIndentColumn int lastNotSpaceOnlyLineIndentColumn int spaceOnlyIndentColumn int foldedNewLine bool isRawFolded bool isLiteral bool isFolded bool } var ( ctxPool = sync.Pool{ New: func() interface{} { return createContext() }, } ) func createContext() *Context { return &Context{ idx: 0, tokens: token.Tokens{}, } } func newContext(src []rune) *Context { ctx, _ := ctxPool.Get().(*Context) ctx.reset(src) return ctx } func (c *Context) release() { ctxPool.Put(c) } func (c *Context) clear() { c.resetBuffer() c.mstate = nil } func (c *Context) reset(src []rune) { c.idx = 0 c.size = len(src) c.src = src c.tokens = c.tokens[:0] c.resetBuffer() c.mstate = nil } func (c *Context) resetBuffer() { c.buf = c.buf[:0] c.obuf = c.obuf[:0] c.notSpaceCharPos = 0 c.notSpaceOrgCharPos = 0 } func (c *Context) breakMultiLine() { c.mstate = nil } func (c *Context) getMultiLineState() *MultiLineState { return c.mstate } func (c *Context) setLiteral(lastDelimColumn int, opt string) { mstate := &MultiLineState{ isLiteral: true, opt: opt, } indent := firstLineIndentColumnByOpt(opt) if indent > 0 { mstate.firstLineIndentColumn = lastDelimColumn + indent } c.mstate = mstate } func (c *Context) setFolded(lastDelimColumn int, opt string) { mstate := &MultiLineState{ isFolded: true, opt: opt, } indent := firstLineIndentColumnByOpt(opt) if indent > 0 { mstate.firstLineIndentColumn = lastDelimColumn + indent } c.mstate = mstate } func (c *Context) setRawFolded(column int) { mstate := &MultiLineState{ isRawFolded: true, } mstate.updateIndentColumn(column) c.mstate = mstate } func firstLineIndentColumnByOpt(opt string) int { opt = strings.TrimPrefix(opt, "-") opt = strings.TrimPrefix(opt, "+") opt = strings.TrimSuffix(opt, "-") opt = strings.TrimSuffix(opt, "+") i, _ := strconv.ParseInt(opt, 10, 64) return int(i) } func (s *MultiLineState) lastDelimColumn() int { if s.firstLineIndentColumn == 0 { return 0 } return s.firstLineIndentColumn - 1 } func (s *MultiLineState) updateIndentColumn(column int) { if s.firstLineIndentColumn == 0 { s.firstLineIndentColumn = column } if s.lineIndentColumn == 0 { s.lineIndentColumn = column } } func (s *MultiLineState) updateSpaceOnlyIndentColumn(column int) { if s.firstLineIndentColumn != 0 { return } s.spaceOnlyIndentColumn = column } func (s *MultiLineState) validateIndentAfterSpaceOnly(column int) error { if s.firstLineIndentColumn != 0 { return nil } if s.spaceOnlyIndentColumn > column { return errors.New("invalid number of indent is specified after space only") } return nil } func (s *MultiLineState) validateIndentColumn() error { if firstLineIndentColumnByOpt(s.opt) == 0 { return nil } if s.firstLineIndentColumn > s.lineIndentColumn { return errors.New("invalid number of indent is specified in the multi-line header") } return nil } func (s *MultiLineState) updateNewLineState() { s.prevLineIndentColumn = s.lineIndentColumn if s.lineIndentColumn != 0 { s.lastNotSpaceOnlyLineIndentColumn = s.lineIndentColumn } s.foldedNewLine = true s.lineIndentColumn = 0 } func (s *MultiLineState) isIndentColumn(column int) bool { if s.firstLineIndentColumn == 0 { return column == 1 } return s.firstLineIndentColumn > column } func (s *MultiLineState) addIndent(ctx *Context, column int) { if s.firstLineIndentColumn == 0 { return } // If the first line of the document has already been evaluated, the number is treated as the threshold, since the `firstLineIndentColumn` is a positive number. if column < s.firstLineIndentColumn { return } // `c.foldedNewLine` is a variable that is set to true for every newline. if !s.isLiteral && s.foldedNewLine { s.foldedNewLine = false } // Since addBuf ignore space character, add to the buffer directly. ctx.buf = append(ctx.buf, ' ') ctx.notSpaceCharPos = len(ctx.buf) } // updateNewLineInFolded if Folded or RawFolded context and the content on the current line starts at the same column as the previous line, // treat the new-line-char as a space. func (s *MultiLineState) updateNewLineInFolded(ctx *Context, column int) { if s.isLiteral { return } // Folded or RawFolded. if !s.foldedNewLine { return } var ( lastChar rune prevLastChar rune ) if len(ctx.buf) != 0 { lastChar = ctx.buf[len(ctx.buf)-1] } if len(ctx.buf) > 1 { prevLastChar = ctx.buf[len(ctx.buf)-2] } if s.lineIndentColumn == s.prevLineIndentColumn { // --- // > // a // b if lastChar == '\n' { ctx.buf[len(ctx.buf)-1] = ' ' } } else if s.prevLineIndentColumn == 0 && s.lastNotSpaceOnlyLineIndentColumn == column { // if previous line is indent-space and new-line-char only, prevLineIndentColumn is zero. // In this case, last new-line-char is removed. // --- // > // a // // b if lastChar == '\n' && prevLastChar == '\n' { ctx.buf = ctx.buf[:len(ctx.buf)-1] ctx.notSpaceCharPos = len(ctx.buf) } } s.foldedNewLine = false } func (s *MultiLineState) hasTrimAllEndNewlineOpt() bool { return strings.HasPrefix(s.opt, "-") || strings.HasSuffix(s.opt, "-") || s.isRawFolded } func (s *MultiLineState) hasKeepAllEndNewlineOpt() bool { return strings.HasPrefix(s.opt, "+") || strings.HasSuffix(s.opt, "+") } func (c *Context) addToken(tk *token.Token) { if tk == nil { return } c.tokens = append(c.tokens, tk) } func (c *Context) addBuf(r rune) { if len(c.buf) == 0 && (r == ' ' || r == '\t') { return } c.buf = append(c.buf, r) if r != ' ' && r != '\t' { c.notSpaceCharPos = len(c.buf) } } func (c *Context) addBufWithTab(r rune) { if len(c.buf) == 0 && r == ' ' { return } c.buf = append(c.buf, r) if r != ' ' { c.notSpaceCharPos = len(c.buf) } } func (c *Context) addOriginBuf(r rune) { c.obuf = append(c.obuf, r) if r != ' ' && r != '\t' { c.notSpaceOrgCharPos = len(c.obuf) } } func (c *Context) removeRightSpaceFromBuf() { trimmedBuf := c.obuf[:c.notSpaceOrgCharPos] buflen := len(trimmedBuf) diff := len(c.obuf) - buflen if diff > 0 { c.obuf = c.obuf[:buflen] c.buf = c.bufferedSrc() } } func (c *Context) isEOS() bool { return len(c.src)-1 <= c.idx } func (c *Context) isNextEOS() bool { return len(c.src) <= c.idx+1 } func (c *Context) next() bool { return c.idx < c.size } func (c *Context) source(s, e int) string { return string(c.src[s:e]) } func (c *Context) previousChar() rune { if c.idx > 0 { return c.src[c.idx-1] } return rune(0) } func (c *Context) currentChar() rune { if c.size > c.idx { return c.src[c.idx] } return rune(0) } func (c *Context) nextChar() rune { if c.size > c.idx+1 { return c.src[c.idx+1] } return rune(0) } func (c *Context) repeatNum(r rune) int { cnt := 0 for i := c.idx; i < c.size; i++ { if c.src[i] == r { cnt++ } else { break } } return cnt } func (c *Context) progress(num int) { c.idx += num } func (c *Context) existsBuffer() bool { return len(c.bufferedSrc()) != 0 } func (c *Context) isMultiLine() bool { return c.mstate != nil } func (c *Context) bufferedSrc() []rune { src := c.buf[:c.notSpaceCharPos] if c.isMultiLine() { mstate := c.getMultiLineState() // remove end '\n' character and trailing empty lines. // https://yaml.org/spec/1.2.2/#8112-block-chomping-indicator if mstate.hasTrimAllEndNewlineOpt() { // If the '-' flag is specified, all trailing newline characters will be removed. src = []rune(strings.TrimRight(string(src), "\n")) } else if !mstate.hasKeepAllEndNewlineOpt() { // Normally, all but one of the trailing newline characters are removed. var newLineCharCount int for i := len(src) - 1; i >= 0; i-- { if src[i] == '\n' { newLineCharCount++ continue } break } removedNewLineCharCount := newLineCharCount - 1 for removedNewLineCharCount > 0 { src = []rune(strings.TrimSuffix(string(src), "\n")) removedNewLineCharCount-- } } // If the text ends with a space character, remove all of them. if mstate.hasTrimAllEndNewlineOpt() { src = []rune(strings.TrimRight(string(src), " ")) } if string(src) == "\n" { // If the content consists only of a newline, // it can be considered as the document ending without any specified value, // so it is treated as an empty string. src = []rune{} } if mstate.hasKeepAllEndNewlineOpt() && len(src) == 0 { src = []rune{'\n'} } } return src } func (c *Context) bufferedToken(pos *token.Position) *token.Token { if c.idx == 0 { return nil } source := c.bufferedSrc() if len(source) == 0 { c.buf = c.buf[:0] // clear value's buffer only. return nil } var tk *token.Token if c.isMultiLine() { tk = token.String(string(source), string(c.obuf), pos) } else { tk = token.New(string(source), string(c.obuf), pos) } c.setTokenTypeByPrevTag(tk) c.resetBuffer() return tk } func (c *Context) setTokenTypeByPrevTag(tk *token.Token) { lastTk := c.lastToken() if lastTk == nil { return } if lastTk.Type != token.TagType { return } tag := token.ReservedTagKeyword(lastTk.Value) if _, exists := token.ReservedTagKeywordMap[tag]; !exists { tk.Type = token.StringType } } func (c *Context) lastToken() *token.Token { if len(c.tokens) != 0 { return c.tokens[len(c.tokens)-1] } return nil } goccy-go-yaml-52dacb8/scanner/error.go000066400000000000000000000004401501576637100177750ustar00rootroot00000000000000package scanner import "github.com/goccy/go-yaml/token" type InvalidTokenError struct { Token *token.Token } func (e *InvalidTokenError) Error() string { return e.Token.Error } func ErrInvalidToken(tk *token.Token) *InvalidTokenError { return &InvalidTokenError{ Token: tk, } } goccy-go-yaml-52dacb8/scanner/scanner.go000066400000000000000000001050721501576637100203040ustar00rootroot00000000000000package scanner import ( "errors" "fmt" "io" "strconv" "strings" "github.com/goccy/go-yaml/token" ) // IndentState state for indent type IndentState int const ( // IndentStateEqual equals previous indent IndentStateEqual IndentState = iota // IndentStateUp more indent than previous IndentStateUp // IndentStateDown less indent than previous IndentStateDown // IndentStateKeep uses not indent token IndentStateKeep ) // Scanner holds the scanner's internal state while processing a given text. // It can be allocated as part of another data structure but must be initialized via Init before use. type Scanner struct { source []rune sourcePos int sourceSize int // line number. This number starts from 1. line int // column number. This number starts from 1. column int // offset represents the offset from the beginning of the source. offset int // lastDelimColumn is the last column needed to compare indent is retained. lastDelimColumn int // indentNum indicates the number of spaces used for indentation. indentNum int // prevLineIndentNum indicates the number of spaces used for indentation at previous line. prevLineIndentNum int // indentLevel indicates the level of indent depth. This value does not match the column value. indentLevel int isFirstCharAtLine bool isAnchor bool isAlias bool isDirective bool startedFlowSequenceNum int startedFlowMapNum int indentState IndentState savedPos *token.Position } func (s *Scanner) pos() *token.Position { return &token.Position{ Line: s.line, Column: s.column, Offset: s.offset, IndentNum: s.indentNum, IndentLevel: s.indentLevel, } } func (s *Scanner) bufferedToken(ctx *Context) *token.Token { if s.savedPos != nil { tk := ctx.bufferedToken(s.savedPos) s.savedPos = nil return tk } line := s.line column := s.column - len(ctx.buf) level := s.indentLevel if ctx.isMultiLine() { line -= s.newLineCount(ctx.buf) column = strings.Index(string(ctx.obuf), string(ctx.buf)) + 1 // Since we are in a literal, folded or raw folded // we can use the indent level from the last token. last := ctx.lastToken() if last != nil { // The last token should never be nil here. level = last.Position.IndentLevel + 1 } } return ctx.bufferedToken(&token.Position{ Line: line, Column: column, Offset: s.offset - len(ctx.buf), IndentNum: s.indentNum, IndentLevel: level, }) } func (s *Scanner) progressColumn(ctx *Context, num int) { s.column += num s.offset += num s.progress(ctx, num) } func (s *Scanner) progressOnly(ctx *Context, num int) { s.offset += num s.progress(ctx, num) } func (s *Scanner) progressLine(ctx *Context) { s.prevLineIndentNum = s.indentNum s.column = 1 s.line++ s.offset++ s.indentNum = 0 s.isFirstCharAtLine = true s.isAnchor = false s.isAlias = false s.isDirective = false s.progress(ctx, 1) } func (s *Scanner) progress(ctx *Context, num int) { ctx.progress(num) s.sourcePos += num } func (s *Scanner) isNewLineChar(c rune) bool { if c == '\n' { return true } if c == '\r' { return true } return false } func (s *Scanner) newLineCount(src []rune) int { size := len(src) cnt := 0 for i := 0; i < size; i++ { c := src[i] switch c { case '\r': if i+1 < size && src[i+1] == '\n' { i++ } cnt++ case '\n': cnt++ } } return cnt } func (s *Scanner) updateIndentLevel() { if s.prevLineIndentNum < s.indentNum { s.indentLevel++ } else if s.prevLineIndentNum > s.indentNum { if s.indentLevel > 0 { s.indentLevel-- } } } func (s *Scanner) updateIndentState(ctx *Context) { if s.lastDelimColumn == 0 { return } if s.lastDelimColumn < s.column { s.indentState = IndentStateUp } else { // If lastDelimColumn and s.column are the same, // treat as Down state since it is the same column as delimiter. s.indentState = IndentStateDown } } func (s *Scanner) updateIndent(ctx *Context, c rune) { if s.isFirstCharAtLine && s.isNewLineChar(c) { return } if s.isFirstCharAtLine && c == ' ' { s.indentNum++ return } if s.isFirstCharAtLine && c == '\t' { // found tab indent. // In this case, scanTab returns error. return } if !s.isFirstCharAtLine { s.indentState = IndentStateKeep return } s.updateIndentLevel() s.updateIndentState(ctx) s.isFirstCharAtLine = false } func (s *Scanner) isChangedToIndentStateDown() bool { return s.indentState == IndentStateDown } func (s *Scanner) isChangedToIndentStateUp() bool { return s.indentState == IndentStateUp } func (s *Scanner) addBufferedTokenIfExists(ctx *Context) { ctx.addToken(s.bufferedToken(ctx)) } func (s *Scanner) breakMultiLine(ctx *Context) { ctx.breakMultiLine() } func (s *Scanner) scanSingleQuote(ctx *Context) (*token.Token, error) { ctx.addOriginBuf('\'') srcpos := s.pos() startIndex := ctx.idx + 1 src := ctx.src size := len(src) value := []rune{} isFirstLineChar := false isNewLine := false for idx := startIndex; idx < size; idx++ { if !isNewLine { s.progressColumn(ctx, 1) } else { isNewLine = false } c := src[idx] ctx.addOriginBuf(c) if s.isNewLineChar(c) { notSpaceIdx := -1 for i := len(value) - 1; i >= 0; i-- { if value[i] == ' ' { continue } notSpaceIdx = i break } if len(value) > notSpaceIdx { value = value[:notSpaceIdx+1] } if isFirstLineChar { value = append(value, '\n') } else { value = append(value, ' ') } isFirstLineChar = true isNewLine = true s.progressLine(ctx) if idx+1 < size { if err := s.validateDocumentSeparatorMarker(ctx, src[idx+1:]); err != nil { return nil, err } } continue } else if isFirstLineChar && c == ' ' { continue } else if isFirstLineChar && c == '\t' { if s.lastDelimColumn >= s.column { return nil, ErrInvalidToken( token.Invalid( "tab character cannot be used for indentation in single-quoted text", string(ctx.obuf), s.pos(), ), ) } continue } else if c != '\'' { value = append(value, c) isFirstLineChar = false continue } else if idx+1 < len(ctx.src) && ctx.src[idx+1] == '\'' { // '' handle as ' character value = append(value, c) ctx.addOriginBuf(c) idx++ s.progressColumn(ctx, 1) continue } s.progressColumn(ctx, 1) return token.SingleQuote(string(value), string(ctx.obuf), srcpos), nil } s.progressColumn(ctx, 1) return nil, ErrInvalidToken( token.Invalid( "could not find end character of single-quoted text", string(ctx.obuf), srcpos, ), ) } func hexToInt(b rune) int { if b >= 'A' && b <= 'F' { return int(b) - 'A' + 10 } if b >= 'a' && b <= 'f' { return int(b) - 'a' + 10 } return int(b) - '0' } func hexRunesToInt(b []rune) int { sum := 0 for i := 0; i < len(b); i++ { sum += hexToInt(b[i]) << (uint(len(b)-i-1) * 4) } return sum } func (s *Scanner) scanDoubleQuote(ctx *Context) (*token.Token, error) { ctx.addOriginBuf('"') srcpos := s.pos() startIndex := ctx.idx + 1 src := ctx.src size := len(src) value := []rune{} isFirstLineChar := false isNewLine := false for idx := startIndex; idx < size; idx++ { if !isNewLine { s.progressColumn(ctx, 1) } else { isNewLine = false } c := src[idx] ctx.addOriginBuf(c) if s.isNewLineChar(c) { notSpaceIdx := -1 for i := len(value) - 1; i >= 0; i-- { if value[i] == ' ' { continue } notSpaceIdx = i break } if len(value) > notSpaceIdx { value = value[:notSpaceIdx+1] } if isFirstLineChar { value = append(value, '\n') } else { value = append(value, ' ') } isFirstLineChar = true isNewLine = true s.progressLine(ctx) if idx+1 < size { if err := s.validateDocumentSeparatorMarker(ctx, src[idx+1:]); err != nil { return nil, err } } continue } else if isFirstLineChar && c == ' ' { continue } else if isFirstLineChar && c == '\t' { if s.lastDelimColumn >= s.column { return nil, ErrInvalidToken( token.Invalid( "tab character cannot be used for indentation in double-quoted text", string(ctx.obuf), s.pos(), ), ) } continue } else if c == '\\' { isFirstLineChar = false if idx+1 >= size { value = append(value, c) continue } nextChar := src[idx+1] progress := 0 switch nextChar { case '0': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x00) case 'a': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x07) case 'b': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x08) case 't': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x09) case 'n': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x0A) case 'v': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x0B) case 'f': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x0C) case 'r': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x0D) case 'e': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x1B) case ' ': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x20) case '"': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x22) case '/': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x2F) case '\\': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x5C) case 'N': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x85) case '_': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0xA0) case 'L': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x2028) case 'P': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, 0x2029) case 'x': if idx+3 >= size { progress = 1 ctx.addOriginBuf(nextChar) value = append(value, nextChar) } else { progress = 3 codeNum := hexRunesToInt(src[idx+2 : idx+progress+1]) value = append(value, rune(codeNum)) } case 'u': // \u0000 style must have 5 characters at least. if idx+5 >= size { return nil, ErrInvalidToken( token.Invalid( "not enough length for escaped UTF-16 character", string(ctx.obuf), s.pos(), ), ) } progress = 5 codeNum := hexRunesToInt(src[idx+2 : idx+6]) // handle surrogate pairs. if codeNum >= 0xD800 && codeNum <= 0xDBFF { high := codeNum // \u0000\u0000 style must have 11 characters at least. if idx+11 >= size { return nil, ErrInvalidToken( token.Invalid( "not enough length for escaped UTF-16 surrogate pair", string(ctx.obuf), s.pos(), ), ) } if src[idx+6] != '\\' || src[idx+7] != 'u' { return nil, ErrInvalidToken( token.Invalid( "found unexpected character after high surrogate for UTF-16 surrogate pair", string(ctx.obuf), s.pos(), ), ) } low := hexRunesToInt(src[idx+8 : idx+12]) if low < 0xDC00 || low > 0xDFFF { return nil, ErrInvalidToken( token.Invalid( "found unexpected low surrogate after high surrogate", string(ctx.obuf), s.pos(), ), ) } codeNum = ((high - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000 progress += 6 } value = append(value, rune(codeNum)) case 'U': // \U00000000 style must have 9 characters at least. if idx+9 >= size { return nil, ErrInvalidToken( token.Invalid( "not enough length for escaped UTF-32 character", string(ctx.obuf), s.pos(), ), ) } progress = 9 codeNum := hexRunesToInt(src[idx+2 : idx+10]) value = append(value, rune(codeNum)) case '\n': isFirstLineChar = true isNewLine = true ctx.addOriginBuf(nextChar) s.progressColumn(ctx, 1) s.progressLine(ctx) idx++ continue case '\r': isFirstLineChar = true isNewLine = true ctx.addOriginBuf(nextChar) s.progressLine(ctx) progress = 1 // Skip \n after \r in CRLF sequences if idx+2 < size && src[idx+2] == '\n' { ctx.addOriginBuf('\n') progress = 2 } case '\t': progress = 1 ctx.addOriginBuf(nextChar) value = append(value, nextChar) default: s.progressColumn(ctx, 1) return nil, ErrInvalidToken( token.Invalid( fmt.Sprintf("found unknown escape character %q", nextChar), string(ctx.obuf), s.pos(), ), ) } idx += progress s.progressColumn(ctx, progress) continue } else if c == '\t' { var ( foundNotSpaceChar bool progress int ) for i := idx + 1; i < size; i++ { if src[i] == ' ' || src[i] == '\t' { progress++ continue } if s.isNewLineChar(src[i]) { break } foundNotSpaceChar = true } if foundNotSpaceChar { value = append(value, c) if src[idx+1] != '"' { s.progressColumn(ctx, 1) } } else { idx += progress s.progressColumn(ctx, progress) } continue } else if c != '"' { value = append(value, c) isFirstLineChar = false continue } s.progressColumn(ctx, 1) return token.DoubleQuote(string(value), string(ctx.obuf), srcpos), nil } s.progressColumn(ctx, 1) return nil, ErrInvalidToken( token.Invalid( "could not find end character of double-quoted text", string(ctx.obuf), srcpos, ), ) } func (s *Scanner) validateDocumentSeparatorMarker(ctx *Context, src []rune) error { if s.foundDocumentSeparatorMarker(src) { return ErrInvalidToken( token.Invalid("found unexpected document separator", string(ctx.obuf), s.pos()), ) } return nil } func (s *Scanner) foundDocumentSeparatorMarker(src []rune) bool { if len(src) < 3 { return false } var marker string if len(src) == 3 { marker = string(src) } else { marker = strings.TrimRightFunc(string(src[:4]), func(r rune) bool { return r == ' ' || r == '\t' || r == '\n' || r == '\r' }) } return marker == "---" || marker == "..." } func (s *Scanner) scanQuote(ctx *Context, ch rune) (bool, error) { if ctx.existsBuffer() { return false, nil } if ch == '\'' { tk, err := s.scanSingleQuote(ctx) if err != nil { return false, err } ctx.addToken(tk) } else { tk, err := s.scanDoubleQuote(ctx) if err != nil { return false, err } ctx.addToken(tk) } ctx.clear() return true, nil } func (s *Scanner) scanWhiteSpace(ctx *Context) bool { if ctx.isMultiLine() { return false } if !s.isAnchor && !s.isDirective && !s.isAlias && !s.isFirstCharAtLine { return false } if s.isFirstCharAtLine { s.progressColumn(ctx, 1) ctx.addOriginBuf(' ') return true } if s.isDirective { s.addBufferedTokenIfExists(ctx) s.progressColumn(ctx, 1) ctx.addOriginBuf(' ') return true } s.addBufferedTokenIfExists(ctx) s.isAnchor = false s.isAlias = false return true } func (s *Scanner) isMergeKey(ctx *Context) bool { if ctx.repeatNum('<') != 2 { return false } src := ctx.src size := len(src) for idx := ctx.idx + 2; idx < size; idx++ { c := src[idx] if c == ' ' { continue } if c != ':' { return false } if idx+1 < size { nc := src[idx+1] if nc == ' ' || s.isNewLineChar(nc) { return true } } } return false } func (s *Scanner) scanTag(ctx *Context) (bool, error) { if ctx.existsBuffer() || s.isDirective { return false, nil } ctx.addOriginBuf('!') s.progress(ctx, 1) // skip '!' character var progress int for idx, c := range ctx.src[ctx.idx:] { progress = idx + 1 switch c { case ' ': ctx.addOriginBuf(c) value := ctx.source(ctx.idx-1, ctx.idx+idx) ctx.addToken(token.Tag(value, string(ctx.obuf), s.pos())) s.progressColumn(ctx, len([]rune(value))) ctx.clear() return true, nil case ',': if s.startedFlowSequenceNum > 0 || s.startedFlowMapNum > 0 { value := ctx.source(ctx.idx-1, ctx.idx+idx) ctx.addToken(token.Tag(value, string(ctx.obuf), s.pos())) s.progressColumn(ctx, len([]rune(value))-1) // progress column before collect-entry for scanning it at scanFlowEntry function. ctx.clear() return true, nil } else { ctx.addOriginBuf(c) } case '\n', '\r': ctx.addOriginBuf(c) value := ctx.source(ctx.idx-1, ctx.idx+idx) ctx.addToken(token.Tag(value, string(ctx.obuf), s.pos())) s.progressColumn(ctx, len([]rune(value))-1) // progress column before new-line-char for scanning new-line-char at scanNewLine function. ctx.clear() return true, nil case '{', '}': ctx.addOriginBuf(c) s.progressColumn(ctx, progress) invalidTk := token.Invalid(fmt.Sprintf("found invalid tag character %q", c), string(ctx.obuf), s.pos()) return false, ErrInvalidToken(invalidTk) default: ctx.addOriginBuf(c) } } s.progressColumn(ctx, progress) ctx.clear() return true, nil } func (s *Scanner) scanComment(ctx *Context) bool { if ctx.existsBuffer() { c := ctx.previousChar() if c != ' ' && c != '\t' && !s.isNewLineChar(c) { return false } } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf('#') s.progress(ctx, 1) // skip '#' character for idx, c := range ctx.src[ctx.idx:] { ctx.addOriginBuf(c) if !s.isNewLineChar(c) { continue } if ctx.previousChar() == '\\' { continue } value := ctx.source(ctx.idx, ctx.idx+idx) progress := len([]rune(value)) ctx.addToken(token.Comment(value, string(ctx.obuf), s.pos())) s.progressColumn(ctx, progress) s.progressLine(ctx) ctx.clear() return true } // document ends with comment. value := string(ctx.src[ctx.idx:]) ctx.addToken(token.Comment(value, string(ctx.obuf), s.pos())) progress := len([]rune(value)) s.progressColumn(ctx, progress) s.progressLine(ctx) ctx.clear() return true } func (s *Scanner) scanMultiLine(ctx *Context, c rune) error { state := ctx.getMultiLineState() ctx.addOriginBuf(c) if ctx.isEOS() { if s.isFirstCharAtLine && c == ' ' { state.addIndent(ctx, s.column) } else { ctx.addBuf(c) } state.updateIndentColumn(s.column) if err := state.validateIndentColumn(); err != nil { invalidTk := token.Invalid(err.Error(), string(ctx.obuf), s.pos()) s.progressColumn(ctx, 1) return ErrInvalidToken(invalidTk) } value := ctx.bufferedSrc() ctx.addToken(token.String(string(value), string(ctx.obuf), s.pos())) ctx.clear() s.progressColumn(ctx, 1) } else if s.isNewLineChar(c) { ctx.addBuf(c) state.updateSpaceOnlyIndentColumn(s.column - 1) state.updateNewLineState() s.progressLine(ctx) if ctx.next() { if s.foundDocumentSeparatorMarker(ctx.src[ctx.idx:]) { value := ctx.bufferedSrc() ctx.addToken(token.String(string(value), string(ctx.obuf), s.pos())) ctx.clear() s.breakMultiLine(ctx) } } } else if s.isFirstCharAtLine && c == ' ' { state.addIndent(ctx, s.column) s.progressColumn(ctx, 1) } else if s.isFirstCharAtLine && c == '\t' && state.isIndentColumn(s.column) { err := ErrInvalidToken( token.Invalid( "found a tab character where an indentation space is expected", string(ctx.obuf), s.pos(), ), ) s.progressColumn(ctx, 1) return err } else if c == '\t' && !state.isIndentColumn(s.column) { ctx.addBufWithTab(c) s.progressColumn(ctx, 1) } else { if err := state.validateIndentAfterSpaceOnly(s.column); err != nil { invalidTk := token.Invalid(err.Error(), string(ctx.obuf), s.pos()) s.progressColumn(ctx, 1) return ErrInvalidToken(invalidTk) } state.updateIndentColumn(s.column) if err := state.validateIndentColumn(); err != nil { invalidTk := token.Invalid(err.Error(), string(ctx.obuf), s.pos()) s.progressColumn(ctx, 1) return ErrInvalidToken(invalidTk) } if col := state.lastDelimColumn(); col > 0 { s.lastDelimColumn = col } state.updateNewLineInFolded(ctx, s.column) ctx.addBufWithTab(c) s.progressColumn(ctx, 1) } return nil } func (s *Scanner) scanNewLine(ctx *Context, c rune) { if len(ctx.buf) > 0 && s.savedPos == nil { bufLen := len(ctx.bufferedSrc()) s.savedPos = s.pos() s.savedPos.Column -= bufLen s.savedPos.Offset -= bufLen } // if the following case, origin buffer has unnecessary two spaces. // So, `removeRightSpaceFromOriginBuf` remove them, also fix column number too. // --- // a:[space][space] // b: c ctx.removeRightSpaceFromBuf() // There is no problem that we ignore CR which followed by LF and normalize it to LF, because of following YAML1.2 spec. // > Line breaks inside scalar content must be normalized by the YAML processor. Each such line break must be parsed into a single line feed character. // > Outside scalar content, YAML allows any line break to be used to terminate lines. // > -- https://yaml.org/spec/1.2/spec.html if c == '\r' && ctx.nextChar() == '\n' { ctx.addOriginBuf('\r') s.progress(ctx, 1) s.offset++ c = '\n' } if ctx.isEOS() { s.addBufferedTokenIfExists(ctx) } else if s.isAnchor || s.isAlias || s.isDirective { s.addBufferedTokenIfExists(ctx) } if ctx.existsBuffer() && s.isFirstCharAtLine { if ctx.buf[len(ctx.buf)-1] == ' ' { ctx.buf[len(ctx.buf)-1] = '\n' } else { ctx.buf = append(ctx.buf, '\n') } } else { ctx.addBuf(' ') } ctx.addOriginBuf(c) s.progressLine(ctx) } func (s *Scanner) isFlowMode() bool { if s.startedFlowSequenceNum > 0 { return true } if s.startedFlowMapNum > 0 { return true } return false } func (s *Scanner) scanFlowMapStart(ctx *Context) bool { if ctx.existsBuffer() && !s.isFlowMode() { return false } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf('{') ctx.addToken(token.MappingStart(string(ctx.obuf), s.pos())) s.startedFlowMapNum++ s.progressColumn(ctx, 1) ctx.clear() return true } func (s *Scanner) scanFlowMapEnd(ctx *Context) bool { if s.startedFlowMapNum <= 0 { return false } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf('}') ctx.addToken(token.MappingEnd(string(ctx.obuf), s.pos())) s.startedFlowMapNum-- s.progressColumn(ctx, 1) ctx.clear() return true } func (s *Scanner) scanFlowArrayStart(ctx *Context) bool { if ctx.existsBuffer() && !s.isFlowMode() { return false } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf('[') ctx.addToken(token.SequenceStart(string(ctx.obuf), s.pos())) s.startedFlowSequenceNum++ s.progressColumn(ctx, 1) ctx.clear() return true } func (s *Scanner) scanFlowArrayEnd(ctx *Context) bool { if ctx.existsBuffer() && s.startedFlowSequenceNum <= 0 { return false } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf(']') ctx.addToken(token.SequenceEnd(string(ctx.obuf), s.pos())) s.startedFlowSequenceNum-- s.progressColumn(ctx, 1) ctx.clear() return true } func (s *Scanner) scanFlowEntry(ctx *Context, c rune) bool { if s.startedFlowSequenceNum <= 0 && s.startedFlowMapNum <= 0 { return false } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf(c) ctx.addToken(token.CollectEntry(string(ctx.obuf), s.pos())) s.progressColumn(ctx, 1) ctx.clear() return true } func (s *Scanner) scanMapDelim(ctx *Context) (bool, error) { nc := ctx.nextChar() if s.isDirective || s.isAnchor || s.isAlias { return false, nil } if s.startedFlowMapNum <= 0 && nc != ' ' && nc != '\t' && !s.isNewLineChar(nc) && !ctx.isNextEOS() { return false, nil } if s.startedFlowMapNum > 0 && nc == '/' { // like http:// return false, nil } if s.startedFlowMapNum > 0 { tk := ctx.lastToken() if tk != nil && tk.Type == token.MappingValueType { return false, nil } } if strings.HasPrefix(strings.TrimPrefix(string(ctx.obuf), " "), "\t") && !strings.HasPrefix(string(ctx.buf), "\t") { invalidTk := token.Invalid("tab character cannot use as a map key directly", string(ctx.obuf), s.pos()) s.progressColumn(ctx, 1) return false, ErrInvalidToken(invalidTk) } // mapping value tk := s.bufferedToken(ctx) if tk != nil { s.lastDelimColumn = tk.Position.Column ctx.addToken(tk) } else if tk := ctx.lastToken(); tk != nil { // If the map key is quote, the buffer does not exist because it has already been cut into tokens. // Therefore, we need to check the last token. if tk.Indicator == token.QuotedScalarIndicator { s.lastDelimColumn = tk.Position.Column } } ctx.addToken(token.MappingValue(s.pos())) s.progressColumn(ctx, 1) ctx.clear() return true, nil } func (s *Scanner) scanDocumentStart(ctx *Context) bool { if s.indentNum != 0 { return false } if s.column != 1 { return false } if ctx.repeatNum('-') != 3 { return false } if ctx.size > ctx.idx+3 { c := ctx.src[ctx.idx+3] if c != ' ' && c != '\t' && c != '\n' && c != '\r' { return false } } s.addBufferedTokenIfExists(ctx) ctx.addToken(token.DocumentHeader(string(ctx.obuf)+"---", s.pos())) s.progressColumn(ctx, 3) ctx.clear() s.clearState() return true } func (s *Scanner) scanDocumentEnd(ctx *Context) bool { if s.indentNum != 0 { return false } if s.column != 1 { return false } if ctx.repeatNum('.') != 3 { return false } s.addBufferedTokenIfExists(ctx) ctx.addToken(token.DocumentEnd(string(ctx.obuf)+"...", s.pos())) s.progressColumn(ctx, 3) ctx.clear() return true } func (s *Scanner) scanMergeKey(ctx *Context) bool { if !s.isMergeKey(ctx) { return false } s.lastDelimColumn = s.column ctx.addToken(token.MergeKey(string(ctx.obuf)+"<<", s.pos())) s.progressColumn(ctx, 2) ctx.clear() return true } func (s *Scanner) scanRawFoldedChar(ctx *Context) bool { if !ctx.existsBuffer() { return false } if !s.isChangedToIndentStateUp() { return false } ctx.setRawFolded(s.column) ctx.addBuf('-') ctx.addOriginBuf('-') s.progressColumn(ctx, 1) return true } func (s *Scanner) scanSequence(ctx *Context) (bool, error) { if ctx.existsBuffer() { return false, nil } nc := ctx.nextChar() if nc != 0 && nc != ' ' && nc != '\t' && !s.isNewLineChar(nc) { return false, nil } if strings.HasPrefix(strings.TrimPrefix(string(ctx.obuf), " "), "\t") { invalidTk := token.Invalid("tab character cannot use as a sequence delimiter", string(ctx.obuf), s.pos()) s.progressColumn(ctx, 1) return false, ErrInvalidToken(invalidTk) } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf('-') tk := token.SequenceEntry(string(ctx.obuf), s.pos()) s.lastDelimColumn = tk.Position.Column ctx.addToken(tk) s.progressColumn(ctx, 1) ctx.clear() return true, nil } func (s *Scanner) scanMultiLineHeader(ctx *Context) (bool, error) { if ctx.existsBuffer() { return false, nil } if err := s.scanMultiLineHeaderOption(ctx); err != nil { return false, err } s.progressLine(ctx) return true, nil } func (s *Scanner) validateMultiLineHeaderOption(opt string) error { if len(opt) == 0 { return nil } orgOpt := opt opt = strings.TrimPrefix(opt, "-") opt = strings.TrimPrefix(opt, "+") opt = strings.TrimSuffix(opt, "-") opt = strings.TrimSuffix(opt, "+") if len(opt) == 0 { return nil } if opt == "0" { return fmt.Errorf("invalid header option: %q", orgOpt) } i, err := strconv.ParseInt(opt, 10, 64) if err != nil { return fmt.Errorf("invalid header option: %q", orgOpt) } if i > 9 { return fmt.Errorf("invalid header option: %q", orgOpt) } return nil } func (s *Scanner) scanMultiLineHeaderOption(ctx *Context) error { header := ctx.currentChar() ctx.addOriginBuf(header) s.progress(ctx, 1) // skip '|' or '>' character var progress int for idx, c := range ctx.src[ctx.idx:] { progress = idx ctx.addOriginBuf(c) if s.isNewLineChar(c) { break } } value := strings.TrimRight(ctx.source(ctx.idx, ctx.idx+progress), " ") commentValueIndex := strings.Index(value, "#") opt := value if commentValueIndex > 0 { opt = value[:commentValueIndex] } opt = strings.TrimRightFunc(opt, func(r rune) bool { return r == ' ' || r == '\t' }) if len(opt) != 0 { if err := s.validateMultiLineHeaderOption(opt); err != nil { invalidTk := token.Invalid(err.Error(), string(ctx.obuf), s.pos()) s.progressColumn(ctx, progress) return ErrInvalidToken(invalidTk) } } if s.column == 1 { s.lastDelimColumn = 1 } commentIndex := strings.Index(string(ctx.obuf), "#") headerBuf := string(ctx.obuf) if commentIndex > 0 { headerBuf = headerBuf[:commentIndex] } switch header { case '|': ctx.addToken(token.Literal("|"+opt, headerBuf, s.pos())) ctx.setLiteral(s.lastDelimColumn, opt) case '>': ctx.addToken(token.Folded(">"+opt, headerBuf, s.pos())) ctx.setFolded(s.lastDelimColumn, opt) } if commentIndex > 0 { comment := string(value[commentValueIndex+1:]) s.offset += len(headerBuf) s.column += len(headerBuf) ctx.addToken(token.Comment(comment, string(ctx.obuf[len(headerBuf):]), s.pos())) } s.indentState = IndentStateKeep ctx.resetBuffer() s.progressColumn(ctx, progress) return nil } func (s *Scanner) scanMapKey(ctx *Context) bool { if ctx.existsBuffer() { return false } nc := ctx.nextChar() if nc != ' ' && nc != '\t' { return false } tk := token.MappingKey(s.pos()) s.lastDelimColumn = tk.Position.Column ctx.addToken(tk) s.progressColumn(ctx, 1) ctx.clear() return true } func (s *Scanner) scanDirective(ctx *Context) bool { if ctx.existsBuffer() { return false } if s.indentNum != 0 { return false } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf('%') ctx.addToken(token.Directive(string(ctx.obuf), s.pos())) s.progressColumn(ctx, 1) ctx.clear() s.isDirective = true return true } func (s *Scanner) scanAnchor(ctx *Context) bool { if ctx.existsBuffer() { return false } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf('&') ctx.addToken(token.Anchor(string(ctx.obuf), s.pos())) s.progressColumn(ctx, 1) s.isAnchor = true ctx.clear() return true } func (s *Scanner) scanAlias(ctx *Context) bool { if ctx.existsBuffer() { return false } s.addBufferedTokenIfExists(ctx) ctx.addOriginBuf('*') ctx.addToken(token.Alias(string(ctx.obuf), s.pos())) s.progressColumn(ctx, 1) s.isAlias = true ctx.clear() return true } func (s *Scanner) scanReservedChar(ctx *Context, c rune) error { if ctx.existsBuffer() { return nil } ctx.addBuf(c) ctx.addOriginBuf(c) err := ErrInvalidToken( token.Invalid( fmt.Sprintf("%q is a reserved character", c), string(ctx.obuf), s.pos(), ), ) s.progressColumn(ctx, 1) ctx.clear() return err } func (s *Scanner) scanTab(ctx *Context, c rune) error { if s.startedFlowSequenceNum > 0 || s.startedFlowMapNum > 0 { // tabs character is allowed in flow mode. return nil } if !s.isFirstCharAtLine { return nil } ctx.addBuf(c) ctx.addOriginBuf(c) err := ErrInvalidToken( token.Invalid("found character '\t' that cannot start any token", string(ctx.obuf), s.pos(), ), ) s.progressColumn(ctx, 1) ctx.clear() return err } func (s *Scanner) scan(ctx *Context) error { for ctx.next() { c := ctx.currentChar() // First, change the IndentState. // If the target character is the first character in a line, IndentState is Up/Down/Equal state. // The second and subsequent letters are Keep. s.updateIndent(ctx, c) // If IndentState is down, tokens are split, so the buffer accumulated until that point needs to be cutted as a token. if s.isChangedToIndentStateDown() { s.addBufferedTokenIfExists(ctx) } if ctx.isMultiLine() { if s.isChangedToIndentStateDown() { if tk := ctx.lastToken(); tk != nil { // If literal/folded content is empty, no string token is added. // Therefore, add an empty string token. // But if literal/folded token column is 1, it is invalid at down state. if tk.Position.Column == 1 { return ErrInvalidToken( token.Invalid( "could not find multi-line content", string(ctx.obuf), s.pos(), ), ) } if tk.Type != token.StringType { ctx.addToken(token.String("", "", s.pos())) } } s.breakMultiLine(ctx) } else { if err := s.scanMultiLine(ctx, c); err != nil { return err } continue } } switch c { case '{': if s.scanFlowMapStart(ctx) { continue } case '}': if s.scanFlowMapEnd(ctx) { continue } case '.': if s.scanDocumentEnd(ctx) { continue } case '<': if s.scanMergeKey(ctx) { continue } case '-': if s.scanDocumentStart(ctx) { continue } if s.scanRawFoldedChar(ctx) { continue } scanned, err := s.scanSequence(ctx) if err != nil { return err } if scanned { continue } case '[': if s.scanFlowArrayStart(ctx) { continue } case ']': if s.scanFlowArrayEnd(ctx) { continue } case ',': if s.scanFlowEntry(ctx, c) { continue } case ':': scanned, err := s.scanMapDelim(ctx) if err != nil { return err } if scanned { continue } case '|', '>': scanned, err := s.scanMultiLineHeader(ctx) if err != nil { return err } if scanned { continue } case '!': scanned, err := s.scanTag(ctx) if err != nil { return err } if scanned { continue } case '%': if s.scanDirective(ctx) { continue } case '?': if s.scanMapKey(ctx) { continue } case '&': if s.scanAnchor(ctx) { continue } case '*': if s.scanAlias(ctx) { continue } case '#': if s.scanComment(ctx) { continue } case '\'', '"': scanned, err := s.scanQuote(ctx, c) if err != nil { return err } if scanned { continue } case '\r', '\n': s.scanNewLine(ctx, c) continue case ' ': if s.scanWhiteSpace(ctx) { continue } case '@', '`': if err := s.scanReservedChar(ctx, c); err != nil { return err } case '\t': if ctx.existsBuffer() && s.lastDelimColumn == 0 { // tab indent for plain text (yaml-test-suite's spec-example-7-12-plain-lines). s.indentNum++ ctx.addOriginBuf(c) s.progressOnly(ctx, 1) continue } if s.lastDelimColumn < s.column { s.indentNum++ ctx.addOriginBuf(c) s.progressOnly(ctx, 1) continue } if err := s.scanTab(ctx, c); err != nil { return err } } ctx.addBuf(c) ctx.addOriginBuf(c) s.progressColumn(ctx, 1) } s.addBufferedTokenIfExists(ctx) return nil } // Init prepares the scanner s to tokenize the text src by setting the scanner at the beginning of src. func (s *Scanner) Init(text string) { src := []rune(text) s.source = src s.sourcePos = 0 s.sourceSize = len(src) s.line = 1 s.column = 1 s.offset = 1 s.isFirstCharAtLine = true s.clearState() } func (s *Scanner) clearState() { s.prevLineIndentNum = 0 s.lastDelimColumn = 0 s.indentLevel = 0 s.indentNum = 0 } // Scan scans the next token and returns the token collection. The source end is indicated by io.EOF. func (s *Scanner) Scan() (token.Tokens, error) { if s.sourcePos >= s.sourceSize { return nil, io.EOF } ctx := newContext(s.source[s.sourcePos:]) defer ctx.release() var tokens token.Tokens err := s.scan(ctx) tokens = append(tokens, ctx.tokens...) if err != nil { var invalidTokenErr *InvalidTokenError if errors.As(err, &invalidTokenErr) { tokens = append(tokens, invalidTokenErr.Token) } return tokens, err } return tokens, nil } goccy-go-yaml-52dacb8/stdlib_quote.go000066400000000000000000000063041501576637100177160ustar00rootroot00000000000000// Copied and trimmed down from https://github.com/golang/go/blob/e3769299cd3484e018e0e2a6e1b95c2b18ce4f41/src/strconv/quote.go // We want to use the standard library's private "quoteWith" function rather than write our own so that we get robust unicode support. // Every private function called by quoteWith was copied. // There are 2 modifications to simplify the code: // 1. The unicode.IsPrint function was substituted for the custom implementation of IsPrint // 2. All code paths reachable only when ASCIIonly or grphicOnly are set to true were removed. // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package yaml import ( "unicode" "unicode/utf8" ) const ( lowerhex = "0123456789abcdef" ) func quoteWith(s string, quote byte) string { return string(appendQuotedWith(make([]byte, 0, 3*len(s)/2), s, quote)) } func appendQuotedWith(buf []byte, s string, quote byte) []byte { // Often called with big strings, so preallocate. If there's quoting, // this is conservative but still helps a lot. if cap(buf)-len(buf) < len(s) { nBuf := make([]byte, len(buf), len(buf)+1+len(s)+1) copy(nBuf, buf) buf = nBuf } buf = append(buf, quote) for width := 0; len(s) > 0; s = s[width:] { r := rune(s[0]) width = 1 if r >= utf8.RuneSelf { r, width = utf8.DecodeRuneInString(s) } if width == 1 && r == utf8.RuneError { buf = append(buf, `\x`...) buf = append(buf, lowerhex[s[0]>>4]) buf = append(buf, lowerhex[s[0]&0xF]) continue } buf = appendEscapedRune(buf, r, quote) } buf = append(buf, quote) return buf } func appendEscapedRune(buf []byte, r rune, quote byte) []byte { var runeTmp [utf8.UTFMax]byte // goccy/go-yaml patch on top of the standard library's appendEscapedRune function. // // We use this to implement the YAML single-quoted string, where the only escape sequence is '', which represents a single quote. // The below snippet from the standard library is for escaping e.g. \ with \\, which is not what we want for the single-quoted string. // // if r == rune(quote) || r == '\\' { // always backslashed // buf = append(buf, '\\') // buf = append(buf, byte(r)) // return buf // } if r == rune(quote) { buf = append(buf, byte(r)) buf = append(buf, byte(r)) return buf } if unicode.IsPrint(r) { n := utf8.EncodeRune(runeTmp[:], r) buf = append(buf, runeTmp[:n]...) return buf } switch r { case '\a': buf = append(buf, `\a`...) case '\b': buf = append(buf, `\b`...) case '\f': buf = append(buf, `\f`...) case '\n': buf = append(buf, `\n`...) case '\r': buf = append(buf, `\r`...) case '\t': buf = append(buf, `\t`...) case '\v': buf = append(buf, `\v`...) default: switch { case r < ' ': buf = append(buf, `\x`...) buf = append(buf, lowerhex[byte(r)>>4]) buf = append(buf, lowerhex[byte(r)&0xF]) case r > utf8.MaxRune: r = 0xFFFD fallthrough case r < 0x10000: buf = append(buf, `\u`...) for s := 12; s >= 0; s -= 4 { buf = append(buf, lowerhex[r>>uint(s)&0xF]) } default: buf = append(buf, `\U`...) for s := 28; s >= 0; s -= 4 { buf = append(buf, lowerhex[r>>uint(s)&0xF]) } } } return buf } goccy-go-yaml-52dacb8/struct.go000066400000000000000000000053361501576637100165500ustar00rootroot00000000000000package yaml import ( "fmt" "reflect" "strings" ) const ( // StructTagName tag keyword for Marshal/Unmarshal StructTagName = "yaml" ) // StructField information for each the field in structure type StructField struct { FieldName string RenderName string AnchorName string AliasName string IsAutoAnchor bool IsAutoAlias bool IsOmitEmpty bool IsOmitZero bool IsFlow bool IsInline bool } func getTag(field reflect.StructField) string { // If struct tag `yaml` exist, use that. If no `yaml` // exists, but `json` does, use that and try the best to // adhere to its rules tag := field.Tag.Get(StructTagName) if tag == "" { tag = field.Tag.Get(`json`) } return tag } func structField(field reflect.StructField) *StructField { tag := getTag(field) fieldName := strings.ToLower(field.Name) options := strings.Split(tag, ",") if len(options) > 0 { if options[0] != "" { fieldName = options[0] } } sf := &StructField{ FieldName: field.Name, RenderName: fieldName, } if len(options) > 1 { for _, opt := range options[1:] { switch { case opt == "omitempty": sf.IsOmitEmpty = true case opt == "omitzero": sf.IsOmitZero = true case opt == "flow": sf.IsFlow = true case opt == "inline": sf.IsInline = true case strings.HasPrefix(opt, "anchor"): anchor := strings.Split(opt, "=") if len(anchor) > 1 { sf.AnchorName = anchor[1] } else { sf.IsAutoAnchor = true } case strings.HasPrefix(opt, "alias"): alias := strings.Split(opt, "=") if len(alias) > 1 { sf.AliasName = alias[1] } else { sf.IsAutoAlias = true } default: } } } return sf } func isIgnoredStructField(field reflect.StructField) bool { if field.PkgPath != "" && !field.Anonymous { // private field return true } return getTag(field) == "-" } type StructFieldMap map[string]*StructField func (m StructFieldMap) isIncludedRenderName(name string) bool { for _, v := range m { if !v.IsInline && v.RenderName == name { return true } } return false } func (m StructFieldMap) hasMergeProperty() bool { for _, v := range m { if v.IsOmitEmpty && v.IsInline && v.IsAutoAlias { return true } } return false } func structFieldMap(structType reflect.Type) (StructFieldMap, error) { fieldMap := StructFieldMap{} renderNameMap := map[string]struct{}{} for i := 0; i < structType.NumField(); i++ { field := structType.Field(i) if isIgnoredStructField(field) { continue } sf := structField(field) if _, exists := renderNameMap[sf.RenderName]; exists { return nil, fmt.Errorf("duplicated struct field name %s", sf.RenderName) } fieldMap[sf.FieldName] = sf renderNameMap[sf.RenderName] = struct{}{} } return fieldMap, nil } goccy-go-yaml-52dacb8/testdata/000077500000000000000000000000001501576637100164775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/anchor.yml000066400000000000000000000000301501576637100204650ustar00rootroot00000000000000a: &a b: 1 c: hello goccy-go-yaml-52dacb8/testdata/go_test.mod000066400000000000000000000010211501576637100206360ustar00rootroot00000000000000module github.com/goccy/go-yaml go 1.21.0 require ( github.com/go-playground/validator/v10 v10.22.1 github.com/google/go-cmp v0.6.0 ) require ( github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/leodido/go-urn v1.4.0 // indirect golang.org/x/crypto v0.28.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect ) goccy-go-yaml-52dacb8/testdata/go_test.sum000066400000000000000000000050451501576637100206750ustar00rootroot00000000000000github.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/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 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/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= goccy-go-yaml-52dacb8/testdata/validate_test.go000066400000000000000000000124111501576637100216550ustar00rootroot00000000000000package yaml_test import ( "strings" "testing" "github.com/go-playground/validator/v10" "github.com/goccy/go-yaml" ) func TestStructValidator(t *testing.T) { type Inner struct { Required string `validate:"required"` Lt10 int `validate:"lt=10"` } cases := []struct { TestName string YAMLContent string ExpectedErr string Instance interface{} }{ { TestName: "Test Simple Validation", YAMLContent: `--- - name: john age: 20 - name: tom age: -1 - name: ken age: 10`, ExpectedErr: `[5:8] Key: 'Age' Error:Field validation for 'Age' failed on the 'gte' tag 2 | - name: john 3 | age: 20 4 | - name: tom > 5 | age: -1 ^ 6 | - name: ken 7 | age: 10`, Instance: &[]struct { Name string `yaml:"name" validate:"required"` Age int `yaml:"age" validate:"gte=0,lt=120"` }{}, }, { TestName: "Test Missing Required Field", YAMLContent: `--- - name: john age: 20 - age: 10`, ExpectedErr: `[4:1] Key: 'Name' Error:Field validation for 'Name' failed on the 'required' tag 1 | --- 2 | - name: john 3 | age: 20 > 4 | - age: 10 ^ `, Instance: &[]struct { Name string `yaml:"name" validate:"required"` Age int `yaml:"age" validate:"gte=0,lt=120"` }{}, }, { TestName: "Test Nested Validation Missing Internal Required", YAMLContent: `--- name: john age: 10 addr: number: seven`, ExpectedErr: `[4:5] Key: 'State' Error:Field validation for 'State' failed on the 'required' tag 1 | --- 2 | name: john 3 | age: 10 > 4 | addr: ^ 5 | number: seven`, Instance: &struct { Name string `yaml:"name" validate:"required"` Age int `yaml:"age" validate:"gte=0,lt=120"` Addr struct { Number string `yaml:"number" validate:"required"` State string `yaml:"state" validate:"required"` } `yaml:"addr"` }{}, }, { TestName: "Test nested Validation with unknown field", YAMLContent: `--- name: john age: 20 addr: number: seven state: washington error: error `, ExpectedErr: `[7:3] unknown field "error" 4 | addr: 5 | number: seven 6 | state: washington > 7 | error: error ^ `, Instance: &struct { Name string `yaml:"name" validate:"required"` Age int `yaml:"age" validate:"gte=0,lt=120"` Addr *struct { Number string `yaml:"number" validate:"required"` State string `yaml:"state" validate:"required"` } `yaml:"addr" validate:"required"` }{}, }, { TestName: "Test Validation with wrong field type", YAMLContent: `--- name: myDocument roles: name: myRole permissions: - hello - how - are - you `, ExpectedErr: `[4:7] mapping was used where sequence is expected 1 | --- 2 | name: myDocument 3 | roles: > 4 | name: myRole ^ 5 | permissions: 6 | - hello 7 | - how 8 | `, Instance: &struct { Name string `yaml:"name"` Roles []struct { Name string `yaml:"name"` Permissions []string `yaml:"permissions"` } `yaml:"roles"` }{}, }, { TestName: "Test inline validation missing required", YAMLContent: `--- name: john age: 20 `, ExpectedErr: `Key: 'Inner.Required' Error:Field validation for 'Required' failed on the 'required' tag`, Instance: &struct { Name string `yaml:"name" validate:"required"` Age int `yaml:"age" validate:"gte=0,lt=120"` Inner `yaml:",inline"` }{}, }, { TestName: "Test inline validation field error", YAMLContent: `--- name: john age: 20 required: present lt10: 20 `, ExpectedErr: `[5:7] Key: 'Inner.Lt10' Error:Field validation for 'Lt10' failed on the 'lt' tag 2 | name: john 3 | age: 20 4 | required: present > 5 | lt10: 20 ^ `, Instance: &struct { Name string `yaml:"name" validate:"required"` Age int `yaml:"age" validate:"gte=0,lt=120"` Inner `yaml:",inline"` }{}, }, { TestName: "Test map", YAMLContent: ` map: hello: hello hello2: hello`, ExpectedErr: `[2:4] Key: 'Map' Error:Field validation for 'Map' failed on the 'eq' tag > 2 | map: ^ 3 | hello: hello 4 | hello2: hello`, Instance: &struct { // Make sure that this map is not set Map map[string]string `yaml:"map" validate:"eq=0"` }{}, }, { TestName: "Test sequence", YAMLContent: ` map: - value `, ExpectedErr: `[2:4] Key: 'Map' Error:Field validation for 'Map' failed on the 'eq' tag > 2 | map: ^ 3 | - value`, Instance: &struct { // Make sure that this map is not set Map []string `yaml:"map" validate:"eq=0"` }{}, }, } for _, tc := range cases { tc := tc // NOTE: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables t.Run(tc.TestName, func(t *testing.T) { validate := validator.New() dec := yaml.NewDecoder( strings.NewReader(tc.YAMLContent), yaml.Validator(validate), yaml.Strict(), ) err := dec.Decode(tc.Instance) switch { case tc.ExpectedErr != "" && err == nil: t.Fatal("expected error") case tc.ExpectedErr == "" && err != nil: t.Fatalf("unexpected error: %v", err) case tc.ExpectedErr != "" && tc.ExpectedErr != err.Error(): t.Fatalf("expected `%s` but actual `%s`", tc.ExpectedErr, err.Error()) } }) } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/000077500000000000000000000000001501576637100215455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-block-sequence/000077500000000000000000000000001501576637100264705ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-block-sequence/in.json000066400000000000000000000000371501576637100277710ustar00rootroot00000000000000[ "a", "b", "a", "b" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-block-sequence/in.yaml000066400000000000000000000000301501576637100277530ustar00rootroot00000000000000- &a a - &b b - *a - *b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-explicit-block-mapping/000077500000000000000000000000001501576637100301325ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-explicit-block-mapping/in.yaml000066400000000000000000000000231501576637100314170ustar00rootroot00000000000000? &a a : &b b : *a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-explicit-block-mapping/out.yaml000066400000000000000000000000201501576637100316150ustar00rootroot00000000000000&a a: &b b : *a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-flow-objects/000077500000000000000000000000001501576637100261665ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-flow-objects/in.yaml000066400000000000000000000000451501576637100274570ustar00rootroot00000000000000{ &a [a, &b b]: *b, *a : [c, *b, d]} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-flow-objects/out.yaml000066400000000000000000000000471501576637100276620ustar00rootroot00000000000000? &a - a - &b b : *b *a : - c - *b - d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-implicit-block-mapping/000077500000000000000000000000001501576637100301235ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-implicit-block-mapping/in.json000066400000000000000000000000331501576637100314200ustar00rootroot00000000000000{ "a": "b", "b": "a" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-implicit-block-mapping/in.yaml000066400000000000000000000000231501576637100314100ustar00rootroot00000000000000&a a: &b b *b : *a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/aliases-in-implicit-block-mapping/out.yaml000066400000000000000000000000231501576637100316110ustar00rootroot00000000000000&a a: &b b *b : *a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-alias/000077500000000000000000000000001501576637100270045ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-alias/in.json000066400000000000000000000000511501576637100303010ustar00rootroot00000000000000{ "a": "scalar a", "b": "scalar a" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-alias/in.yaml000066400000000000000000000000531501576637100302740ustar00rootroot00000000000000a: &:@*!$": scalar a b: *:@*!$": goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-keys/000077500000000000000000000000001501576637100266665ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-keys/in.json000066400000000000000000000002471501576637100301720ustar00rootroot00000000000000{ "a!\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~": "safe", "?foo": "safe question mark", ":foo": "safe colon", "-foo": "safe dash", "this is#not": "a comment" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-keys/in.yaml000066400000000000000000000001771501576637100301650ustar00rootroot00000000000000a!"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~: safe ?foo: safe question mark :foo: safe colon -foo: safe dash this is#not: a comment goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-keys/out.yaml000066400000000000000000000001771501576637100303660ustar00rootroot00000000000000a!"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~: safe ?foo: safe question mark :foo: safe colon -foo: safe dash this is#not: a comment goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-plain-scalars/000077500000000000000000000000001501576637100304445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-plain-scalars/in.json000066400000000000000000000002621501576637100317450ustar00rootroot00000000000000{ "safe": "a!\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~ !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~", "safe question mark": "?foo", "safe colon": ":foo", "safe dash": "-foo" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-plain-scalars/in.yaml000066400000000000000000000002241501576637100317340ustar00rootroot00000000000000safe: a!"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~ !"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~ safe question mark: ?foo safe colon: :foo safe dash: -foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-plain-scalars/out.yaml000066400000000000000000000002171501576637100321370ustar00rootroot00000000000000safe: a!"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~ !"#$%&'()*+,-./09:;<=>?@AZ[\]^_`az{|}~ safe question mark: ?foo safe colon: :foo safe dash: -foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-quoted-mapping-key/000077500000000000000000000000001501576637100314335ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-quoted-mapping-key/in.json000066400000000000000000000001051501576637100327300ustar00rootroot00000000000000{ "foo\nbar:baz\tx \\$%^&*()x": 23, "x\\ny:z\\tx $%^&*()x": 24 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-quoted-mapping-key/in.yaml000066400000000000000000000000721501576637100327240ustar00rootroot00000000000000"foo\nbar:baz\tx \\$%^&*()x": 23 'x\ny:z\tx $%^&*()x': 24 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/allowed-characters-in-quoted-mapping-key/out.yaml000066400000000000000000000000751501576637100331300ustar00rootroot00000000000000? "foo\nbar:baz\tx \\$%^&*()x" : 23 'x\ny:z\tx $%^&*()x': 24 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-and-alias-as-mapping-key/000077500000000000000000000000001501576637100274665ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-and-alias-as-mapping-key/error000066400000000000000000000000001501576637100305300ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-and-alias-as-mapping-key/in.yaml000066400000000000000000000000471501576637100307610ustar00rootroot00000000000000key1: &alias value1 &b *alias : value2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-before-sequence-entry-on-same-line/000077500000000000000000000000001501576637100315065ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-before-sequence-entry-on-same-line/error000066400000000000000000000000001501576637100325500ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-before-sequence-entry-on-same-line/in.yaml000066400000000000000000000000311501576637100327720ustar00rootroot00000000000000&anchor - sequence entry goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-before-zero-indented-sequence/000077500000000000000000000000001501576637100306325ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-before-zero-indented-sequence/in.json000066400000000000000000000000441501576637100321310ustar00rootroot00000000000000{ "seq": [ "a", "b" ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-before-zero-indented-sequence/in.yaml000066400000000000000000000000321501576637100321170ustar00rootroot00000000000000--- seq: &anchor - a - b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-before-zero-indented-sequence/out.yaml000066400000000000000000000000311501576637100323170ustar00rootroot00000000000000--- seq: &anchor - a - b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-for-empty-node/000077500000000000000000000000001501576637100256625ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-for-empty-node/in.json000066400000000000000000000000351501576637100271610ustar00rootroot00000000000000{ "a": null, "b": null } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-for-empty-node/in.yaml000066400000000000000000000000321501576637100271470ustar00rootroot00000000000000--- a: &anchor b: *anchor goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-for-empty-node/out.yaml000066400000000000000000000000321501576637100273500ustar00rootroot00000000000000--- a: &anchor b: *anchor goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-plus-alias/000077500000000000000000000000001501576637100250675ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-plus-alias/error000066400000000000000000000000001501576637100261310ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-plus-alias/in.yaml000066400000000000000000000000331501576637100263550ustar00rootroot00000000000000key1: &a value key2: &b *a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-with-colon-in-the-middle/000077500000000000000000000000001501576637100275165ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-with-colon-in-the-middle/in.json000066400000000000000000000000251501576637100310140ustar00rootroot00000000000000{ "key": "value" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-with-colon-in-the-middle/in.yaml000066400000000000000000000000301501576637100310010ustar00rootroot00000000000000--- key: &an:chor value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-with-colon-in-the-middle/out.yaml000066400000000000000000000000301501576637100312020ustar00rootroot00000000000000--- key: &an:chor value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-with-unicode-character/000077500000000000000000000000001501576637100273465ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-with-unicode-character/in.json000066400000000000000000000000271501576637100306460ustar00rootroot00000000000000[ "unicode anchor" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-with-unicode-character/in.yaml000066400000000000000000000000331501576637100306340ustar00rootroot00000000000000--- - &😁 unicode anchor goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchor-with-unicode-character/out.yaml000066400000000000000000000000331501576637100310350ustar00rootroot00000000000000--- - &😁 unicode anchor goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-and-tags/000077500000000000000000000000001501576637100246765ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-and-tags/in.json000066400000000000000000000000331501576637100261730ustar00rootroot00000000000000[ "a", 2, 4, "d" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-and-tags/in.yaml000066400000000000000000000000571501576637100261720ustar00rootroot00000000000000 - &a !!str a - !!int 2 - !!int &c 4 - &d d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-and-tags/out.yaml000066400000000000000000000000531501576637100263670ustar00rootroot00000000000000- &a !!str a - !!int 2 - &c !!int 4 - &d d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-in-mapping/000077500000000000000000000000001501576637100252375ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-in-mapping/in.json000066400000000000000000000000331501576637100265340ustar00rootroot00000000000000{ "a": "b", "c": "d" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-in-mapping/in.yaml000066400000000000000000000000201501576637100265210ustar00rootroot00000000000000&a a: b c: &d d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-on-empty-scalars/000077500000000000000000000000001501576637100263765ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-on-empty-scalars/in.yaml000066400000000000000000000001011501576637100276600ustar00rootroot00000000000000- &a - a - &a : a b: &b - &c : &a - ? &d - ? &e : &a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-on-empty-scalars/out.yaml000066400000000000000000000000651501576637100300720ustar00rootroot00000000000000- &a - a - &a : a b: &b - &c : &a - &d : - &e : &a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-with-colon-in-name/000077500000000000000000000000001501576637100266055ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-with-colon-in-name/in.json000066400000000000000000000000451501576637100301050ustar00rootroot00000000000000{ "key": "value", "foo": "key" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-with-colon-in-name/in.yaml000066400000000000000000000000351501576637100300750ustar00rootroot00000000000000&a: key: &a value foo: *a: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/anchors-with-colon-in-name/out.yaml000066400000000000000000000000331501576637100302740ustar00rootroot00000000000000&a: key: &a value foo: *a: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/backslashes-in-singlequotes/000077500000000000000000000000001501576637100271545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/backslashes-in-singlequotes/in.json000066400000000000000000000000331501576637100304510ustar00rootroot00000000000000{ "foo: bar\\": "baz'" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/backslashes-in-singlequotes/in.yaml000066400000000000000000000000221501576637100304400ustar00rootroot00000000000000'foo: bar\': baz' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/backslashes-in-singlequotes/out.yaml000066400000000000000000000000221501576637100306410ustar00rootroot00000000000000'foo: bar\': baz' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bad-indentation-in-mapping-2/000077500000000000000000000000001501576637100270015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bad-indentation-in-mapping-2/error000066400000000000000000000000001501576637100300430ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bad-indentation-in-mapping-2/in.yaml000066400000000000000000000000621501576637100302710ustar00rootroot00000000000000map: key1: "quoted1" key2: "bad indentation" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bad-indentation-in-mapping/000077500000000000000000000000001501576637100266425ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bad-indentation-in-mapping/error000066400000000000000000000000001501576637100277040ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bad-indentation-in-mapping/in.yaml000066400000000000000000000000601501576637100301300ustar00rootroot00000000000000map: key1: "quoted1" key2: "bad indentation" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bare-document-after-document-end-marker/000077500000000000000000000000001501576637100312305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bare-document-after-document-end-marker/in.json000066400000000000000000000000371501576637100325310ustar00rootroot00000000000000"scalar1" { "key": "value" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bare-document-after-document-end-marker/in.yaml000066400000000000000000000000331501576637100325160ustar00rootroot00000000000000--- scalar1 ... key: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/bare-document-after-document-end-marker/out.yaml000066400000000000000000000000331501576637100327170ustar00rootroot00000000000000--- scalar1 ... key: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/blank-lines/000077500000000000000000000000001501576637100237445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/blank-lines/in.json000066400000000000000000000000751501576637100252470ustar00rootroot00000000000000{ "foo": 1, "bar": 2, "text": "a\n \nb\n\nc\n\nd\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/blank-lines/in.yaml000066400000000000000000000000641501576637100252360ustar00rootroot00000000000000foo: 1 bar: 2 text: | a b c d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/blank-lines/out.yaml000066400000000000000000000000531501576637100254350ustar00rootroot00000000000000foo: 1 bar: 2 text: "a\n \nb\n\nc\n\nd\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-missing-keys/000077500000000000000000000000001501576637100276615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-missing-keys/in.yaml000066400000000000000000000000101501576637100311420ustar00rootroot00000000000000: a : b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-missing-values/000077500000000000000000000000001501576637100302055ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-missing-values/in.json000066400000000000000000000000521501576637100315030ustar00rootroot00000000000000{ "a": null, "b": null, "c": null } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-missing-values/in.yaml000066400000000000000000000000131501576637100314710ustar00rootroot00000000000000? a ? b c: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-missing-values/out.yaml000066400000000000000000000000111501576637100316700ustar00rootroot00000000000000a: b: c: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-multiline-scalars/000077500000000000000000000000001501576637100306675ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-multiline-scalars/in.json000066400000000000000000000000511501576637100321640ustar00rootroot00000000000000{ "a true": "null d", "e 42": null } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-multiline-scalars/in.yaml000066400000000000000000000000371501576637100321610ustar00rootroot00000000000000? a true : null d ? e 42 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mapping-with-multiline-scalars/out.yaml000066400000000000000000000000251501576637100323570ustar00rootroot00000000000000a true: null d e 42: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mappings-in-block-sequence/000077500000000000000000000000001501576637100277555ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mappings-in-block-sequence/in.json000066400000000000000000000001231501576637100312520ustar00rootroot00000000000000[ { "key": "value", "key2": "value2" }, { "key3": "value3" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mappings-in-block-sequence/in.yaml000066400000000000000000000000611501576637100312440ustar00rootroot00000000000000 - key: value key2: value2 - key3: value3 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-mappings-in-block-sequence/out.yaml000066400000000000000000000000531501576637100314460ustar00rootroot00000000000000- key: value key2: value2 - key3: value3 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-indicator-order/000077500000000000000000000000001501576637100271655ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-indicator-order/in.json000066400000000000000000000001011501576637100304560ustar00rootroot00000000000000[ "explicit indent and chomp", "chomp and explicit indent" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-indicator-order/in.yaml000066400000000000000000000001041501576637100304520ustar00rootroot00000000000000- |2- explicit indent and chomp - |-2 chomp and explicit indent goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-indicator-order/out.yaml000066400000000000000000000001021501576637100306510ustar00rootroot00000000000000- |- explicit indent and chomp - |- chomp and explicit indent goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-keep/000077500000000000000000000000001501576637100250245ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-keep/in.json000066400000000000000000000000141501576637100263200ustar00rootroot00000000000000"ab\n\n \n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-keep/in.yaml000066400000000000000000000000241501576637100263120ustar00rootroot00000000000000--- |+ ab ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-keep/out.yaml000066400000000000000000000000201501576637100265070ustar00rootroot00000000000000"ab\n\n \n" ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-strip-1-3/000077500000000000000000000000001501576637100255375ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-strip-1-3/in.json000066400000000000000000000000051501576637100270330ustar00rootroot00000000000000"ab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-strip-1-3/in.yaml000066400000000000000000000000231501576637100270240ustar00rootroot00000000000000--- |- ab ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-strip-1-3/out.yaml000066400000000000000000000000201501576637100272220ustar00rootroot00000000000000--- |- ab ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-strip/000077500000000000000000000000001501576637100252415ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-strip/in.json000066400000000000000000000000051501576637100265350ustar00rootroot00000000000000"ab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-strip/in.yaml000066400000000000000000000000171501576637100265310ustar00rootroot00000000000000|- ab ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-strip/out.yaml000066400000000000000000000000141501576637100267270ustar00rootroot00000000000000|- ab ... block-scalar-with-more-spaces-than-first-content-line/000077500000000000000000000000001501576637100336625ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suiteerror000066400000000000000000000000001501576637100347240ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-with-more-spaces-than-first-content-linein.yaml000066400000000000000000000000521501576637100351510ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-with-more-spaces-than-first-content-lineempty block scalar: > # comment block-scalar-with-wrong-indented-line-after-spaces-only/000077500000000000000000000000001501576637100341755ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suiteerror000066400000000000000000000000001501576637100352370ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-with-wrong-indented-line-after-spaces-onlyin.yaml000066400000000000000000000000421501576637100354630ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-scalar-with-wrong-indented-line-after-spaces-onlyblock scalar: > invalid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-in-block-mapping/000077500000000000000000000000001501576637100275725ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-in-block-mapping/in.json000066400000000000000000000000541501576637100310720ustar00rootroot00000000000000{ "key": [ "item1", "item2" ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-in-block-mapping/in.yaml000066400000000000000000000000271501576637100310630ustar00rootroot00000000000000key: - item1 - item2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-in-block-mapping/out.yaml000066400000000000000000000000251501576637100312620ustar00rootroot00000000000000key: - item1 - item2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-in-block-sequence/000077500000000000000000000000001501576637100277475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-in-block-sequence/in.json000066400000000000000000000000551501576637100312500ustar00rootroot00000000000000[ [ "s1_i1", "s1_i2" ], "s2" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-in-block-sequence/in.yaml000066400000000000000000000000311501576637100312330ustar00rootroot00000000000000- - s1_i1 - s1_i2 - s2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-indentation/000077500000000000000000000000001501576637100267575ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-indentation/in.json000066400000000000000000000000671501576637100302630ustar00rootroot00000000000000[ "x\n", { "foo" : "bar" }, [ 42 ] ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-indentation/in.yaml000066400000000000000000000000331501576637100302450ustar00rootroot00000000000000- | x - foo: bar - - 42 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-sequence-indentation/out.yaml000066400000000000000000000000321501576637100304450ustar00rootroot00000000000000- | x - foo: bar - - 42 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-submapping/000077500000000000000000000000001501576637100250025ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-submapping/in.json000066400000000000000000000000541501576637100263020ustar00rootroot00000000000000{ "foo": { "bar": 1 }, "baz": 2 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/block-submapping/in.yaml000066400000000000000000000000251501576637100262710ustar00rootroot00000000000000foo: bar: 1 baz: 2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-and-adjacent-value-after-comment-on-next-line/000077500000000000000000000000001501576637100333525ustar00rootroot00000000000000in.json000066400000000000000000000000231501576637100345670ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-and-adjacent-value-after-comment-on-next-line{ "foo": "bar" } in.yaml000066400000000000000000000000371501576637100345650ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-and-adjacent-value-after-comment-on-next-line--- { "foo" # comment :bar } out.yaml000066400000000000000000000000171501576637100347640ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-and-adjacent-value-after-comment-on-next-line--- "foo": bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-and-adjacent-value-on-next-line/000077500000000000000000000000001501576637100306135ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-and-adjacent-value-on-next-line/in.json000066400000000000000000000000231501576637100321070ustar00rootroot00000000000000{ "foo": "bar" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-and-adjacent-value-on-next-line/in.yaml000066400000000000000000000000251501576637100321020ustar00rootroot00000000000000--- { "foo" :bar } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-and-adjacent-value-on-next-line/out.yaml000066400000000000000000000000171501576637100323040ustar00rootroot00000000000000--- "foo": bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-at-the-beginning-of-adjacent-flow-scalar/000077500000000000000000000000001501576637100323565ustar00rootroot00000000000000in.json000066400000000000000000000000741501576637100336010ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-at-the-beginning-of-adjacent-flow-scalar[ { "key": "value" }, { "key": ":value" } ] in.yaml000066400000000000000000000000451501576637100335700ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-at-the-beginning-of-adjacent-flow-scalar- { "key":value } - { "key"::value } out.yaml000066400000000000000000000000331501576637100337660ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-at-the-beginning-of-adjacent-flow-scalar- key: value - key: :value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-followed-by-comma/000077500000000000000000000000001501576637100261725ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-followed-by-comma/in.json000066400000000000000000000000131501576637100274650ustar00rootroot00000000000000[ ":," ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-followed-by-comma/in.yaml000066400000000000000000000000111501576637100274540ustar00rootroot00000000000000--- - :, goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-followed-by-comma/out.yaml000066400000000000000000000000111501576637100276550ustar00rootroot00000000000000--- - :, goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-in-double-quoted-string/000077500000000000000000000000001501576637100273365ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-in-double-quoted-string/in.json000066400000000000000000000000221501576637100306310ustar00rootroot00000000000000"foo: bar\": baz" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/colon-in-double-quoted-string/in.yaml000066400000000000000000000000221501576637100306220ustar00rootroot00000000000000"foo: bar\": baz" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-and-document-end-marker/000077500000000000000000000000001501576637100276065ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-and-document-end-marker/in.json000066400000000000000000000000001501576637100310750ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-and-document-end-marker/in.yaml000066400000000000000000000000161501576637100310750ustar00rootroot00000000000000# comment ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-and-document-end-marker/out.yaml000066400000000000000000000000001501576637100312670ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-between-plain-scalar-lines/000077500000000000000000000000001501576637100303125ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-between-plain-scalar-lines/error000066400000000000000000000000001501576637100313540ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-between-plain-scalar-lines/in.yaml000066400000000000000000000000271501576637100316030ustar00rootroot00000000000000word1 # comment word2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-in-flow-sequence-before-comma/000077500000000000000000000000001501576637100307205ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-in-flow-sequence-before-comma/in.json000066400000000000000000000000311501576637100322130ustar00rootroot00000000000000[ "word1", "word2" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-in-flow-sequence-before-comma/in.yaml000066400000000000000000000000371501576637100322120ustar00rootroot00000000000000--- [ word1 # comment , word2] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-in-flow-sequence-before-comma/out.yaml000066400000000000000000000000241501576637100324070ustar00rootroot00000000000000--- - word1 - word2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-in-plain-multiline-value/000077500000000000000000000000001501576637100300265ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-in-plain-multiline-value/error000066400000000000000000000000001501576637100310700ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-in-plain-multiline-value/in.yaml000066400000000000000000000000321501576637100313130ustar00rootroot00000000000000key: word1 # xxx word2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-that-looks-like-a-mapping-key/000077500000000000000000000000001501576637100306515ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-that-looks-like-a-mapping-key/error000066400000000000000000000000001501576637100317130ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-that-looks-like-a-mapping-key/in.yaml000066400000000000000000000000371501576637100321430ustar00rootroot00000000000000key: value this is #not a: key comment-without-whitespace-after-block-scalar-indicator/000077500000000000000000000000001501576637100343675ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suiteerror000066400000000000000000000000001501576637100354310ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-without-whitespace-after-block-scalar-indicatorin.yaml000066400000000000000000000000331501576637100356550ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-without-whitespace-after-block-scalar-indicatorblock: ># comment scalar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-without-whitespace-after-doublequoted-scalar/000077500000000000000000000000001501576637100340765ustar00rootroot00000000000000error000066400000000000000000000000001501576637100350610ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-without-whitespace-after-doublequoted-scalarin.yaml000066400000000000000000000000361501576637100353100ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/comment-without-whitespace-after-doublequoted-scalarkey: "value"# invalid comment goccy-go-yaml-52dacb8/testdata/yaml-test-suite/construct-binary/000077500000000000000000000000001501576637100250535ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/construct-binary/in.json000066400000000000000000000011621501576637100263540ustar00rootroot00000000000000{ "canonical": "R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=", "generic": "R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\nOTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\n+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\nAgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=\n", "description": "The binary value above is a tiny arrow encoded as a gif image." } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/construct-binary/in.yaml000066400000000000000000000011741501576637100263500ustar00rootroot00000000000000canonical: !!binary "\ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" generic: !!binary | R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= description: The binary value above is a tiny arrow encoded as a gif image. goccy-go-yaml-52dacb8/testdata/yaml-test-suite/dash-in-flow-sequence/000077500000000000000000000000001501576637100256435ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/dash-in-flow-sequence/error000066400000000000000000000000001501576637100267050ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/dash-in-flow-sequence/in.yaml000066400000000000000000000000041501576637100271270ustar00rootroot00000000000000[-] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-by-itself-with-no-document/000077500000000000000000000000001501576637100306165ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-by-itself-with-no-document/error000066400000000000000000000000001501576637100316600ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-by-itself-with-no-document/in.yaml000066400000000000000000000000121501576637100321010ustar00rootroot00000000000000%YAML 1.2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/000077500000000000000000000000001501576637100253505ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/00/000077500000000000000000000000001501576637100255675ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/00/error000066400000000000000000000000001501576637100266310ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/00/in.yaml000066400000000000000000000000221501576637100270530ustar00rootroot00000000000000%YAML 1.1#... --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/01/000077500000000000000000000000001501576637100255705ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/01/error000066400000000000000000000000001501576637100266320ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/01/in.yaml000066400000000000000000000000341501576637100270570ustar00rootroot00000000000000%YAML 1.2 --- %YAML 1.2 --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/02/000077500000000000000000000000001501576637100255715ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/02/in.json000066400000000000000000000000051501576637100270650ustar00rootroot00000000000000null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/02/in.yaml000066400000000000000000000000171501576637100270610ustar00rootroot00000000000000%YAML 1.1 --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/02/out.yaml000066400000000000000000000000041501576637100272560ustar00rootroot00000000000000--- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/03/000077500000000000000000000000001501576637100255725ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/03/in.json000066400000000000000000000000051501576637100270660ustar00rootroot00000000000000null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/03/in.yaml000066400000000000000000000000201501576637100270540ustar00rootroot00000000000000%YAML 1.1 --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/03/out.yaml000066400000000000000000000000041501576637100272570ustar00rootroot00000000000000--- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/04/000077500000000000000000000000001501576637100255735ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/04/in.json000066400000000000000000000000051501576637100270670ustar00rootroot00000000000000null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/04/in.yaml000066400000000000000000000000311501576637100270570ustar00rootroot00000000000000%YAML 1.1 # comment --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/04/out.yaml000066400000000000000000000000041501576637100272600ustar00rootroot00000000000000--- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/05/000077500000000000000000000000001501576637100255745ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/05/in.json000066400000000000000000000000051501576637100270700ustar00rootroot00000000000000null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/05/in.yaml000066400000000000000000000000151501576637100270620ustar00rootroot00000000000000%YAM 1.1 --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/05/out.yaml000066400000000000000000000000041501576637100272610ustar00rootroot00000000000000--- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/06/000077500000000000000000000000001501576637100255755ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/06/in.json000066400000000000000000000000051501576637100270710ustar00rootroot00000000000000null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/06/in.yaml000066400000000000000000000000171501576637100270650ustar00rootroot00000000000000%YAMLL 1.1 --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-variants/06/out.yaml000066400000000000000000000000041501576637100272620ustar00rootroot00000000000000--- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-without-document/000077500000000000000000000000001501576637100270405ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-without-document/error000066400000000000000000000000001501576637100301020ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/directive-without-document/in.yaml000066400000000000000000000000161501576637100303270ustar00rootroot00000000000000%YAML 1.2 ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-end-marker/000077500000000000000000000000001501576637100254065ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-end-marker/in.json000066400000000000000000000000001501576637100266750ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-end-marker/in.yaml000066400000000000000000000000041501576637100266720ustar00rootroot00000000000000... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-end-marker/out.yaml000066400000000000000000000000001501576637100270670ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-start-on-last-line/000077500000000000000000000000001501576637100270165ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-start-on-last-line/in.json000066400000000000000000000000241501576637100303130ustar00rootroot00000000000000{ "a": "b" } null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-start-on-last-line/in.yaml000066400000000000000000000000151501576637100303040ustar00rootroot00000000000000--- a: b --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-start-on-last-line/out.yaml000066400000000000000000000000211501576637100305020ustar00rootroot00000000000000--- a: b --- ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-with-footer/000077500000000000000000000000001501576637100256305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-with-footer/in.json000066400000000000000000000000231501576637100271240ustar00rootroot00000000000000{ "aaa": "bbb" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/document-with-footer/in.yaml000066400000000000000000000000151501576637100271160ustar00rootroot00000000000000aaa: bbb ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/double-quoted-scalar-with-escaped-single-quote/000077500000000000000000000000001501576637100325465ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/double-quoted-scalar-with-escaped-single-quote/error000066400000000000000000000000001501576637100336100ustar00rootroot00000000000000in.yaml000066400000000000000000000000371501576637100337610ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/double-quoted-scalar-with-escaped-single-quote--- double: "quoted \' scalar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/double-quoted-string-without-closing-quote/000077500000000000000000000000001501576637100321125ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/double-quoted-string-without-closing-quote/error000066400000000000000000000000001501576637100331540ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/double-quoted-string-without-closing-quote/in.yaml000066400000000000000000000000401501576637100333760ustar00rootroot00000000000000--- key: "missing closing quote goccy-go-yaml-52dacb8/testdata/yaml-test-suite/doublequoted-scalar-starting-with-a-tab/000077500000000000000000000000001501576637100312705ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/doublequoted-scalar-starting-with-a-tab/in.json000066400000000000000000000000301501576637100325620ustar00rootroot00000000000000{ "tab": "\tstring" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/doublequoted-scalar-starting-with-a-tab/in.yaml000066400000000000000000000000241501576637100325560ustar00rootroot00000000000000--- tab: "\tstring" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/doublequoted-scalar-starting-with-a-tab/out.yaml000066400000000000000000000000241501576637100327570ustar00rootroot00000000000000--- tab: "\tstring" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/duplicate-yaml-directive/000077500000000000000000000000001501576637100264335ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/duplicate-yaml-directive/error000066400000000000000000000000001501576637100274750ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/duplicate-yaml-directive/in.yaml000066400000000000000000000000301501576637100277160ustar00rootroot00000000000000%YAML 1.2 %YAML 1.2 --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-flow-collections/000077500000000000000000000000001501576637100261645ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-flow-collections/in.json000066400000000000000000000002131501576637100274610ustar00rootroot00000000000000{ "nested sequences": [ [ [ [] ] ], [ [ {} ] ] ], "key1": [], "key2": {} } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-flow-collections/in.yaml000066400000000000000000000000721501576637100274550ustar00rootroot00000000000000--- nested sequences: - - - [] - - - {} key1: [] key2: {} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-flow-collections/out.yaml000066400000000000000000000000721501576637100276560ustar00rootroot00000000000000--- nested sequences: - - - [] - - - {} key1: [] key2: {} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-implicit-key-in-single-pair-flow-sequences/000077500000000000000000000000001501576637100330535ustar00rootroot00000000000000in.yaml000066400000000000000000000000521501576637100342630ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-implicit-key-in-single-pair-flow-sequences- [ : empty key ] - [: another empty key] out.yaml000066400000000000000000000000501501576637100344620ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-implicit-key-in-single-pair-flow-sequences- - : empty key - - : another empty key goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-keys-in-block-and-flow-mapping/000077500000000000000000000000001501576637100305065ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-keys-in-block-and-flow-mapping/in.yaml000066400000000000000000000001701501576637100317760ustar00rootroot00000000000000--- key: value : empty key --- { key: value, : empty key } --- # empty key and value : --- # empty key and value { : } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-lines-at-end-of-document/000077500000000000000000000000001501576637100273775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-lines-at-end-of-document/in.yaml000066400000000000000000000000041501576637100306630ustar00rootroot00000000000000: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-lines-between-mapping-elements/000077500000000000000000000000001501576637100307055ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-lines-between-mapping-elements/in.json000066400000000000000000000000351501576637100322040ustar00rootroot00000000000000{ "one": 2, "three": 4 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-lines-between-mapping-elements/in.yaml000066400000000000000000000000221501576637100321710ustar00rootroot00000000000000one: 2 three: 4 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-lines-between-mapping-elements/out.yaml000066400000000000000000000000201501576637100323700ustar00rootroot00000000000000one: 2 three: 4 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-stream/000077500000000000000000000000001501576637100241745ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-stream/in.json000066400000000000000000000000001501576637100254630ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/empty-stream/in.yaml000066400000000000000000000000001501576637100254540ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/escaped-slash-in-double-quotes/000077500000000000000000000000001501576637100274535ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/escaped-slash-in-double-quotes/in.json000066400000000000000000000000351501576637100307520ustar00rootroot00000000000000{ "escaped slash": "a/b" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/escaped-slash-in-double-quotes/in.yaml000066400000000000000000000000261501576637100307430ustar00rootroot00000000000000escaped slash: "a\/b" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/escaped-slash-in-double-quotes/out.yaml000066400000000000000000000000251501576637100311430ustar00rootroot00000000000000escaped slash: "a/b" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-key-and-value-seperated-by-comment/000077500000000000000000000000001501576637100320505ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-key-and-value-seperated-by-comment/in.json000066400000000000000000000000251501576637100333460ustar00rootroot00000000000000{ "key": "value" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-key-and-value-seperated-by-comment/in.yaml000066400000000000000000000000341501576637100333370ustar00rootroot00000000000000--- ? key # comment : value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-key-and-value-seperated-by-comment/out.yaml000066400000000000000000000000171501576637100335410ustar00rootroot00000000000000--- key: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-non-specific-tag-1-3/000077500000000000000000000000001501576637100270105ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-non-specific-tag-1-3/in.json000066400000000000000000000000041501576637100303030ustar00rootroot00000000000000"a" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-non-specific-tag-1-3/in.yaml000066400000000000000000000000101501576637100302710ustar00rootroot00000000000000--- ! a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-non-specific-tag-1-3/out.yaml000066400000000000000000000000101501576637100304720ustar00rootroot00000000000000--- ! a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-non-specific-tag/000077500000000000000000000000001501576637100265125ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-non-specific-tag/in.json000066400000000000000000000000041501576637100300050ustar00rootroot00000000000000"a" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/explicit-non-specific-tag/in.yaml000066400000000000000000000000041501576637100277760ustar00rootroot00000000000000! a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/extra-words-on-yaml-directive/000077500000000000000000000000001501576637100273525ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/extra-words-on-yaml-directive/error000066400000000000000000000000001501576637100304140ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/extra-words-on-yaml-directive/in.yaml000066400000000000000000000000221501576637100306360ustar00rootroot00000000000000%YAML 1.2 foo --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-collections-over-many-lines/000077500000000000000000000000001501576637100300535ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-collections-over-many-lines/00/000077500000000000000000000000001501576637100302725ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-collections-over-many-lines/00/error000066400000000000000000000000001501576637100313340ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-collections-over-many-lines/00/in.yaml000066400000000000000000000000151501576637100315600ustar00rootroot00000000000000k: { k : v } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-collections-over-many-lines/01/000077500000000000000000000000001501576637100302735ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-collections-over-many-lines/01/in.json000066400000000000000000000000401501576637100315660ustar00rootroot00000000000000{ "k" : { "k" : "v" } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-collections-over-many-lines/01/in.yaml000066400000000000000000000000211501576637100315560ustar00rootroot00000000000000k: { k : v } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-collections-over-many-lines/01/out.yaml000066400000000000000000000000161501576637100317630ustar00rootroot00000000000000--- k: k: v goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/000077500000000000000000000000001501576637100305015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/00/000077500000000000000000000000001501576637100307205ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/00/in.json000066400000000000000000000000231501576637100322140ustar00rootroot00000000000000{ "foo": "bar" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/00/in.yaml000066400000000000000000000000201501576637100322020ustar00rootroot00000000000000{"foo" : "bar"} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/01/000077500000000000000000000000001501576637100307215ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/01/in.json000066400000000000000000000000231501576637100322150ustar00rootroot00000000000000{ "foo": "bar" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/01/in.yaml000066400000000000000000000000161501576637100322100ustar00rootroot00000000000000{"foo" : bar} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/02/000077500000000000000000000000001501576637100307225ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/02/in.json000066400000000000000000000000231501576637100322160ustar00rootroot00000000000000{ "foo": "bar" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-colon-on-line-after-key/02/in.yaml000066400000000000000000000000141501576637100322070ustar00rootroot00000000000000{foo : bar} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-edge-cases/000077500000000000000000000000001501576637100261435ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-edge-cases/in.json000066400000000000000000000000201501576637100274340ustar00rootroot00000000000000{ "x": ":x" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-edge-cases/in.yaml000066400000000000000000000000101501576637100274240ustar00rootroot00000000000000{x: :x} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-edge-cases/out.yaml000066400000000000000000000000061501576637100276320ustar00rootroot00000000000000x: :x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-in-block-sequence/000077500000000000000000000000001501576637100274475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-in-block-sequence/in.json000066400000000000000000000000311501576637100307420ustar00rootroot00000000000000[ { "a": "b" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-in-block-sequence/in.yaml000066400000000000000000000000111501576637100307310ustar00rootroot00000000000000- {a: b} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-in-block-sequence/out.yaml000066400000000000000000000000071501576637100311370ustar00rootroot00000000000000- a: b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-key-on-two-lines/000077500000000000000000000000001501576637100272645ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-key-on-two-lines/error000066400000000000000000000000001501576637100303260ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-key-on-two-lines/in.yaml000066400000000000000000000000121501576637100305470ustar00rootroot00000000000000[23 ]: 42 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-missing-a-separating-comma/000077500000000000000000000000001501576637100312575ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-missing-a-separating-comma/error000066400000000000000000000000001501576637100323210ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-missing-a-separating-comma/in.yaml000066400000000000000000000000301501576637100325420ustar00rootroot00000000000000--- { foo: 1 bar: 2 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-separate-values/000077500000000000000000000000001501576637100272445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-separate-values/in.yaml000066400000000000000000000000731501576637100305360ustar00rootroot00000000000000{ unquoted : "separate", http://foo.com, omitted value:, } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping-separate-values/out.yaml000066400000000000000000000000761501576637100307420ustar00rootroot00000000000000unquoted: "separate" http://foo.com: null omitted value: null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping/000077500000000000000000000000001501576637100241455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping/in.json000066400000000000000000000000431501576637100254430ustar00rootroot00000000000000{ "foo": "you", "bar": "far" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping/in.yaml000066400000000000000000000000251501576637100254340ustar00rootroot00000000000000{foo: you, bar: far} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-mapping/out.yaml000066400000000000000000000000221501576637100256320ustar00rootroot00000000000000foo: you bar: far goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-block-mapping/000077500000000000000000000000001501576637100274475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-block-mapping/in.json000066400000000000000000000000421501576637100307440ustar00rootroot00000000000000{ "a": [ "b", "c" ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-block-mapping/in.yaml000066400000000000000000000000121501576637100307320ustar00rootroot00000000000000a: [b, c] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-block-mapping/out.yaml000066400000000000000000000000131501576637100311340ustar00rootroot00000000000000a: - b - c goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-flow-mapping/000077500000000000000000000000001501576637100273245ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-flow-mapping/in.yaml000066400000000000000000000000271501576637100306150ustar00rootroot00000000000000{a: [b, c], [d, e]: f} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-flow-mapping/out.yaml000066400000000000000000000000331501576637100310130ustar00rootroot00000000000000a: - b - c ? - d - e : f goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-flow-sequence/000077500000000000000000000000001501576637100275015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-flow-sequence/in.json000066400000000000000000000000441501576637100310000ustar00rootroot00000000000000[ "a", [ "b", "c" ] ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-flow-sequence/in.yaml000066400000000000000000000000141501576637100307660ustar00rootroot00000000000000[a, [b, c]] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-in-flow-sequence/out.yaml000066400000000000000000000000201501576637100311640ustar00rootroot00000000000000- a - - b - c goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-with-invalid-comma-at-the-beginning/000077500000000000000000000000001501576637100331275ustar00rootroot00000000000000error000066400000000000000000000000001501576637100341120ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-with-invalid-comma-at-the-beginningin.yaml000066400000000000000000000000221501576637100343340ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-with-invalid-comma-at-the-beginning--- [ , a, b, c ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-with-invalid-extra-closing-bracket/000077500000000000000000000000001501576637100331055ustar00rootroot00000000000000error000066400000000000000000000000001501576637100340700ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-with-invalid-extra-closing-bracketin.yaml000066400000000000000000000000221501576637100343120ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-with-invalid-extra-closing-bracket--- [ a, b, c ] ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-with-invalid-extra-comma/000077500000000000000000000000001501576637100311325ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-with-invalid-extra-comma/error000066400000000000000000000000001501576637100321740ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-with-invalid-extra-comma/in.yaml000066400000000000000000000000231501576637100324170ustar00rootroot00000000000000--- [ a, b, c, , ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-without-closing-bracket/000077500000000000000000000000001501576637100310705ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-without-closing-bracket/error000066400000000000000000000000001501576637100321320ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence-without-closing-bracket/in.yaml000066400000000000000000000000221501576637100323540ustar00rootroot00000000000000--- [ [ a, b, c ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence/000077500000000000000000000000001501576637100243225ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence/in.json000066400000000000000000000000331501576637100256170ustar00rootroot00000000000000[ "foo", "bar", 42 ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence/in.yaml000066400000000000000000000000171501576637100256120ustar00rootroot00000000000000[foo, bar, 42] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/flow-sequence/out.yaml000066400000000000000000000000211501576637100260060ustar00rootroot00000000000000- foo - bar - 42 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/folded-block-scalar-1-3/000077500000000000000000000000001501576637100256335ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/folded-block-scalar-1-3/in.json000066400000000000000000000000241501576637100271300ustar00rootroot00000000000000"ab cd\nef\n\ngh\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/folded-block-scalar-1-3/in.yaml000066400000000000000000000000321501576637100271200ustar00rootroot00000000000000--- > ab cd ef gh goccy-go-yaml-52dacb8/testdata/yaml-test-suite/folded-block-scalar-1-3/out.yaml000066400000000000000000000000331501576637100273220ustar00rootroot00000000000000--- > ab cd ef gh goccy-go-yaml-52dacb8/testdata/yaml-test-suite/folded-block-scalar/000077500000000000000000000000001501576637100253355ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/folded-block-scalar/in.json000066400000000000000000000000241501576637100266320ustar00rootroot00000000000000"ab cd\nef\n\ngh\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/folded-block-scalar/in.yaml000066400000000000000000000000261501576637100266250ustar00rootroot00000000000000> ab cd ef gh goccy-go-yaml-52dacb8/testdata/yaml-test-suite/folded-block-scalar/out.yaml000066400000000000000000000000271501576637100270270ustar00rootroot00000000000000> ab cd ef gh goccy-go-yaml-52dacb8/testdata/yaml-test-suite/implicit-flow-mapping-key-on-one-line/000077500000000000000000000000001501576637100306615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/implicit-flow-mapping-key-on-one-line/in.yaml000066400000000000000000000000161501576637100321500ustar00rootroot00000000000000[flow]: block goccy-go-yaml-52dacb8/testdata/yaml-test-suite/implicit-flow-mapping-key-on-one-line/out.yaml000066400000000000000000000000211501576637100323450ustar00rootroot00000000000000? - flow : block goccy-go-yaml-52dacb8/testdata/yaml-test-suite/implicit-key-followed-by-newline-and-adjacent-value/000077500000000000000000000000001501576637100334465ustar00rootroot00000000000000error000066400000000000000000000000001501576637100344310ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/implicit-key-followed-by-newline-and-adjacent-valuein.yaml000066400000000000000000000000231501576637100346540ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/implicit-key-followed-by-newline-and-adjacent-value[ "key" :value ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/implicit-key-followed-by-newline/000077500000000000000000000000001501576637100300255ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/implicit-key-followed-by-newline/error000066400000000000000000000000001501576637100310670ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/implicit-key-followed-by-newline/in.yaml000066400000000000000000000000261501576637100313150ustar00rootroot00000000000000--- [ key : value ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/000077500000000000000000000000001501576637100271255ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/00/000077500000000000000000000000001501576637100273445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/00/in.json000066400000000000000000000000201501576637100306350ustar00rootroot00000000000000"1 inline\ttab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/00/in.yaml000066400000000000000000000000201501576637100306260ustar00rootroot00000000000000"1 inline\ttab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/01/000077500000000000000000000000001501576637100273455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/01/in.json000066400000000000000000000000201501576637100306360ustar00rootroot00000000000000"2 inline\ttab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/01/in.yaml000066400000000000000000000000201501576637100306270ustar00rootroot00000000000000"2 inline\ tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/01/out.yaml000066400000000000000000000000201501576637100310300ustar00rootroot00000000000000"2 inline\ttab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/02/000077500000000000000000000000001501576637100273465ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/02/in.json000066400000000000000000000000201501576637100306370ustar00rootroot00000000000000"3 inline\ttab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/02/in.yaml000066400000000000000000000000171501576637100306360ustar00rootroot00000000000000"3 inline tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/inline-tabs-in-double-quoted/02/out.yaml000066400000000000000000000000201501576637100310310ustar00rootroot00000000000000"3 inline\ttab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-anchor-in-zero-indented-sequence/000077500000000000000000000000001501576637100314225ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-anchor-in-zero-indented-sequence/error000066400000000000000000000000001501576637100324640ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-anchor-in-zero-indented-sequence/in.yaml000066400000000000000000000000311501576637100327060ustar00rootroot00000000000000--- seq: &anchor - a - b invalid-block-mapping-key-on-same-line-as-previous-key/000077500000000000000000000000001501576637100337465ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suiteerror000066400000000000000000000000001501576637100350100ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-block-mapping-key-on-same-line-as-previous-keyin.yaml000066400000000000000000000000311501576637100352320ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-block-mapping-key-on-same-line-as-previous-key--- x: { y: z }in: valid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-comma-in-tag/000077500000000000000000000000001501576637100254425ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-comma-in-tag/error000066400000000000000000000000001501576637100265040ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-comma-in-tag/in.yaml000066400000000000000000000000151501576637100267300ustar00rootroot00000000000000- !!str, xxx goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-comment-after-comma/000077500000000000000000000000001501576637100270245ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-comment-after-comma/error000066400000000000000000000000001501576637100300660ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-comment-after-comma/in.yaml000066400000000000000000000000311501576637100303100ustar00rootroot00000000000000--- [ a, b, c,#invalid ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-comment-after-end-of-flow-sequence/000077500000000000000000000000001501576637100316535ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-comment-after-end-of-flow-sequence/error000066400000000000000000000000001501576637100327150ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-comment-after-end-of-flow-sequence/in.yaml000066400000000000000000000000311501576637100331370ustar00rootroot00000000000000--- [ a, b, c, ]#invalid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-content-after-document-end-marker/000077500000000000000000000000001501576637100316015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-content-after-document-end-marker/error000066400000000000000000000000001501576637100326430ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-content-after-document-end-marker/in.yaml000066400000000000000000000000331501576637100330670ustar00rootroot00000000000000--- key: value ... invalid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-document-end-marker-in-single-quoted-string/000077500000000000000000000000001501576637100335205ustar00rootroot00000000000000error000066400000000000000000000000001501576637100345030ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-document-end-marker-in-single-quoted-stringin.yaml000066400000000000000000000000141501576637100347260ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-document-end-marker-in-single-quoted-string--- ' ... ' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-document-markers-in-flow-style/000077500000000000000000000000001501576637100311605ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-document-markers-in-flow-style/error000066400000000000000000000000001501576637100322220ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-document-markers-in-flow-style/in.yaml000066400000000000000000000000161501576637100324470ustar00rootroot00000000000000[ --- , ... ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-document-start-marker-in-doublequoted-tring/000077500000000000000000000000001501576637100336405ustar00rootroot00000000000000error000066400000000000000000000000001501576637100346230ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-document-start-marker-in-doublequoted-tringin.yaml000066400000000000000000000000141501576637100350460ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-document-start-marker-in-doublequoted-tring--- " --- " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-escape-in-double-quoted-string/000077500000000000000000000000001501576637100311105ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-escape-in-double-quoted-string/error000066400000000000000000000000001501576637100321520ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-escape-in-double-quoted-string/in.yaml000066400000000000000000000000111501576637100323720ustar00rootroot00000000000000--- "\." goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-item-after-end-of-flow-sequence/000077500000000000000000000000001501576637100311475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-item-after-end-of-flow-sequence/error000066400000000000000000000000001501576637100322110ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-item-after-end-of-flow-sequence/in.yaml000066400000000000000000000000431501576637100324360ustar00rootroot00000000000000--- [ sequence item ] invalid item goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-after-sequence/000077500000000000000000000000001501576637100275315ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-after-sequence/error000066400000000000000000000000001501576637100305730ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-after-sequence/in.yaml000066400000000000000000000000331501576637100310170ustar00rootroot00000000000000- item1 - item2 invalid: x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-in-plain-multiline/000077500000000000000000000000001501576637100303315ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-in-plain-multiline/error000066400000000000000000000000001501576637100313730ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-in-plain-multiline/in.yaml000066400000000000000000000000261501576637100316210ustar00rootroot00000000000000this is invalid: x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-in-plain-scalar/000077500000000000000000000000001501576637100275745ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-in-plain-scalar/error000066400000000000000000000000001501576637100306360ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-in-plain-scalar/in.yaml000066400000000000000000000000351501576637100310640ustar00rootroot00000000000000key: word1 word2 no: key goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-in-plain-single-line-value/000077500000000000000000000000001501576637100316475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-in-plain-single-line-value/error000066400000000000000000000000001501576637100327110ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-mapping-in-plain-single-line-value/in.yaml000066400000000000000000000000131501576637100331330ustar00rootroot00000000000000a: b: c: d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-nested-mapping/000077500000000000000000000000001501576637100261045ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-nested-mapping/error000066400000000000000000000000001501576637100271460ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-nested-mapping/in.yaml000066400000000000000000000000161501576637100273730ustar00rootroot00000000000000--- a: 'b': c goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-scalar-after-sequence/000077500000000000000000000000001501576637100273435ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-scalar-after-sequence/error000066400000000000000000000000001501576637100304050ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-scalar-after-sequence/in.yaml000066400000000000000000000000301501576637100306260ustar00rootroot00000000000000- item1 - item2 invalid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-scalar-at-the-end-of-mapping/000077500000000000000000000000001501576637100304155ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-scalar-at-the-end-of-mapping/error000066400000000000000000000000001501576637100314570ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-scalar-at-the-end-of-mapping/in.yaml000066400000000000000000000000371501576637100317070ustar00rootroot00000000000000key: - item1 - item2 invalid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-scalar-at-the-end-of-sequence/000077500000000000000000000000001501576637100305725ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-scalar-at-the-end-of-sequence/error000066400000000000000000000000001501576637100316340ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-scalar-at-the-end-of-sequence/in.yaml000066400000000000000000000000341501576637100320610ustar00rootroot00000000000000key: - bar - baz invalid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-sequene-item-on-same-line-as-previous-item/000077500000000000000000000000001501576637100332635ustar00rootroot00000000000000error000066400000000000000000000000001501576637100342460ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-sequene-item-on-same-line-as-previous-itemin.yaml000066400000000000000000000000301501576637100344670ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-sequene-item-on-same-line-as-previous-item--- - { y: z }- invalid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-tabs-as-indendation-in-a-mapping/000077500000000000000000000000001501576637100312705ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-tabs-as-indendation-in-a-mapping/error000066400000000000000000000000001501576637100323320ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-tabs-as-indendation-in-a-mapping/in.yaml000066400000000000000000000000261501576637100325600ustar00rootroot00000000000000--- a: b: c: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-tag/000077500000000000000000000000001501576637100237445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-tag/error000066400000000000000000000000001501576637100250060ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-tag/in.yaml000066400000000000000000000000311501576637100252300ustar00rootroot00000000000000--- !invalid{}tag scalar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-text-after-block-scalar-indicator/000077500000000000000000000000001501576637100315615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-text-after-block-scalar-indicator/error000066400000000000000000000000001501576637100326230ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-text-after-block-scalar-indicator/in.yaml000066400000000000000000000000471501576637100330540ustar00rootroot00000000000000--- folded: > first line second line goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-value-after-mapping/000077500000000000000000000000001501576637100270355ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-value-after-mapping/error000066400000000000000000000000001501576637100300770ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/invalid-value-after-mapping/in.yaml000066400000000000000000000000231501576637100303220ustar00rootroot00000000000000foo: bar invalid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/key-with-anchor-after-missing-explicit-mapping-value/000077500000000000000000000000001501576637100337065ustar00rootroot00000000000000in.json000066400000000000000000000000441501576637100351260ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/key-with-anchor-after-missing-explicit-mapping-value{ "a": 1, "b": null, "c": 3 } in.yaml000066400000000000000000000000321501576637100351140ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/key-with-anchor-after-missing-explicit-mapping-value--- a: 1 ? b &anchor c: 3 out.yaml000066400000000000000000000000311501576637100353140ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/key-with-anchor-after-missing-explicit-mapping-value--- a: 1 b: &anchor c: 3 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tab-content-in-literals/000077500000000000000000000000001501576637100276055ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tab-content-in-literals/00/000077500000000000000000000000001501576637100300245ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tab-content-in-literals/00/in.json000066400000000000000000000000201501576637100313150ustar00rootroot00000000000000{"foo":"\tbar"} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tab-content-in-literals/00/in.yaml000066400000000000000000000000161501576637100313130ustar00rootroot00000000000000foo: |- bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tab-content-in-literals/00/out.yaml000066400000000000000000000000171501576637100315150ustar00rootroot00000000000000foo: |- bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tab-content-in-literals/01/000077500000000000000000000000001501576637100300255ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tab-content-in-literals/01/in.json000066400000000000000000000000201501576637100313160ustar00rootroot00000000000000{"foo":"\tbar"} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tab-content-in-literals/01/in.yaml000066400000000000000000000000151501576637100313130ustar00rootroot00000000000000foo: |- bargoccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tab-content-in-literals/01/out.yaml000066400000000000000000000000171501576637100315160ustar00rootroot00000000000000foo: |- bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/000077500000000000000000000000001501576637100272525ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/00/000077500000000000000000000000001501576637100274715ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/00/in.json000066400000000000000000000000221501576637100307640ustar00rootroot00000000000000"1 leading \ttab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/00/in.yaml000066400000000000000000000000261501576637100307610ustar00rootroot00000000000000"1 leading \ttab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/01/000077500000000000000000000000001501576637100274725ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/01/in.json000066400000000000000000000000221501576637100307650ustar00rootroot00000000000000"2 leading \ttab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/01/in.yaml000066400000000000000000000000261501576637100307620ustar00rootroot00000000000000"2 leading \ tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/02/000077500000000000000000000000001501576637100274735ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/02/in.json000066400000000000000000000000201501576637100307640ustar00rootroot00000000000000"3 leading tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/02/in.yaml000066400000000000000000000000251501576637100307620ustar00rootroot00000000000000"3 leading tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/03/000077500000000000000000000000001501576637100274745ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/03/in.json000066400000000000000000000000241501576637100307710ustar00rootroot00000000000000"4 leading \t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/03/in.yaml000066400000000000000000000000301501576637100307570ustar00rootroot00000000000000"4 leading \t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/04/000077500000000000000000000000001501576637100274755ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/04/in.json000066400000000000000000000000241501576637100307720ustar00rootroot00000000000000"5 leading \t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/04/in.yaml000066400000000000000000000000301501576637100307600ustar00rootroot00000000000000"5 leading \ tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/05/000077500000000000000000000000001501576637100274765ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/05/in.json000066400000000000000000000000201501576637100307670ustar00rootroot00000000000000"6 leading tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/leading-tabs-in-double-quoted/05/in.yaml000066400000000000000000000000271501576637100307670ustar00rootroot00000000000000"6 leading tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/legal-tab-after-indentation/000077500000000000000000000000001501576637100270065ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/legal-tab-after-indentation/in.json000066400000000000000000000000331501576637100303030ustar00rootroot00000000000000{ "x": [ "x x" ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/legal-tab-after-indentation/in.yaml000066400000000000000000000000151501576637100302740ustar00rootroot00000000000000x: - x x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/legal-tab-after-indentation/out.yaml000066400000000000000000000000111501576637100304710ustar00rootroot00000000000000x: - x x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-block-scalar-with-more-spaces-in-first-line/000077500000000000000000000000001501576637100333775ustar00rootroot00000000000000error000066400000000000000000000000001501576637100343620ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-block-scalar-with-more-spaces-in-first-linein.yaml000066400000000000000000000001071501576637100346100ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-block-scalar-with-more-spaces-in-first-line--- block scalar: | more spaces at the beginning are invalid goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-block-scalar/000077500000000000000000000000001501576637100255345ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-block-scalar/in.json000066400000000000000000000000341501576637100270320ustar00rootroot00000000000000{ "a": "ab\n\ncd\nef\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-block-scalar/in.yaml000066400000000000000000000000321501576637100270210ustar00rootroot00000000000000a: | ab cd ef ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-block-scalar/out.yaml000066400000000000000000000000311501576637100272210ustar00rootroot00000000000000a: | ab cd ef ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/000077500000000000000000000000001501576637100250075ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/00/000077500000000000000000000000001501576637100252265ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/00/error000066400000000000000000000000001501576637100262700ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/00/in.yaml000066400000000000000000000000071501576637100265150ustar00rootroot00000000000000--- |0 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/01/000077500000000000000000000000001501576637100252275ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/01/error000066400000000000000000000000001501576637100262710ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/01/in.yaml000066400000000000000000000000101501576637100265100ustar00rootroot00000000000000--- |10 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/02/000077500000000000000000000000001501576637100252305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/02/in.json000066400000000000000000000000031501576637100265220ustar00rootroot00000000000000"" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/02/in.yaml000066400000000000000000000000071501576637100265170ustar00rootroot00000000000000--- |1-goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/03/000077500000000000000000000000001501576637100252315ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/03/in.json000066400000000000000000000000031501576637100265230ustar00rootroot00000000000000"" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-modifers/03/in.yaml000066400000000000000000000000071501576637100265200ustar00rootroot00000000000000--- |1+goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-scalars/000077500000000000000000000000001501576637100246275ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-scalars/in.json000066400000000000000000000000651501576637100261310ustar00rootroot00000000000000[ { "aaa" : "xxx\n", "bbb" : "xxx\n" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-scalars/in.yaml000066400000000000000000000000431501576637100261160ustar00rootroot00000000000000- aaa: |2 xxx bbb: | xxx goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-scalars/out.yaml000066400000000000000000000000461501576637100263220ustar00rootroot00000000000000--- - aaa: | xxx bbb: | xxx goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-unicode/000077500000000000000000000000001501576637100246255ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-unicode/in.json000066400000000000000000000000511501576637100261220ustar00rootroot00000000000000{ "wanted": "love ♥ and peace ☮" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-unicode/in.yaml000066400000000000000000000000431501576637100261140ustar00rootroot00000000000000--- wanted: love ♥ and peace ☮ goccy-go-yaml-52dacb8/testdata/yaml-test-suite/literal-unicode/out.yaml000066400000000000000000000000531501576637100263160ustar00rootroot00000000000000--- wanted: "love \u2665 and peace \u262E" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/lookahead-test-cases/000077500000000000000000000000001501576637100255455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/lookahead-test-cases/in.json000066400000000000000000000001021501576637100270370ustar00rootroot00000000000000[ { "bla\"keks": "foo" }, { "bla]keks": "foo" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/lookahead-test-cases/in.yaml000066400000000000000000000000401501576637100270310ustar00rootroot00000000000000- bla"keks: foo - bla]keks: foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mapping-key-and-flow-sequence-item-anchors/000077500000000000000000000000001501576637100316705ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mapping-key-and-flow-sequence-item-anchors/in.yaml000066400000000000000000000000531501576637100331600ustar00rootroot00000000000000--- &mapping &key [ &item a, b, c ]: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mapping-key-and-flow-sequence-item-anchors/out.yaml000066400000000000000000000000561501576637100333640ustar00rootroot00000000000000--- &mapping ? &key - &item a - b - c : value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mapping-starting-at-line/000077500000000000000000000000001501576637100263605ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mapping-starting-at-line/error000066400000000000000000000000001501576637100274220ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mapping-starting-at-line/in.yaml000066400000000000000000000000421501576637100276460ustar00rootroot00000000000000--- key1: value1 key2: value2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mapping-with-anchor-on-document-start-line/000077500000000000000000000000001501576637100317275ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mapping-with-anchor-on-document-start-line/error000066400000000000000000000000001501576637100327710ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mapping-with-anchor-on-document-start-line/in.yaml000066400000000000000000000000211501576637100332120ustar00rootroot00000000000000--- &anchor a: b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/missing-colon/000077500000000000000000000000001501576637100243265ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/missing-colon/error000066400000000000000000000000001501576637100253700ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/missing-colon/in.yaml000066400000000000000000000000301501576637100256110ustar00rootroot00000000000000top1: key1: val1 top2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/missing-comma-in-flow/000077500000000000000000000000001501576637100256615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/missing-comma-in-flow/error000066400000000000000000000000001501576637100267230ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/missing-comma-in-flow/in.yaml000066400000000000000000000000361501576637100271520ustar00rootroot00000000000000key: [ word1 # xxx word2 ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/missing-document-end-marker-before-directive/000077500000000000000000000000001501576637100322715ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/missing-document-end-marker-before-directive/error000066400000000000000000000000001501576637100333330ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/missing-document-end-marker-before-directive/in.yaml000066400000000000000000000000541501576637100335620ustar00rootroot00000000000000--- scalar1 # comment %YAML 1.2 --- scalar2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mixed-block-mapping-explicit-to-implicit/000077500000000000000000000000001501576637100314435ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mixed-block-mapping-explicit-to-implicit/in.json000066400000000000000000000000411501576637100327370ustar00rootroot00000000000000{ "a": 1.3, "fifteen": "d" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mixed-block-mapping-explicit-to-implicit/in.yaml000066400000000000000000000000251501576637100327320ustar00rootroot00000000000000? a : 1.3 fifteen: d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mixed-block-mapping-explicit-to-implicit/out.yaml000066400000000000000000000000221501576637100331300ustar00rootroot00000000000000a: 1.3 fifteen: d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mixed-block-mapping-implicit-to-explicit/000077500000000000000000000000001501576637100314435ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mixed-block-mapping-implicit-to-explicit/in.json000066400000000000000000000000321501576637100327370ustar00rootroot00000000000000{ "d": 23, "a": 4.2 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mixed-block-mapping-implicit-to-explicit/in.yaml000066400000000000000000000000201501576637100327250ustar00rootroot00000000000000a: 4.2 ? d : 23 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/mixed-block-mapping-implicit-to-explicit/out.yaml000066400000000000000000000000151501576637100331320ustar00rootroot00000000000000a: 4.2 d: 23 more-indented-lines-at-the-beginning-of-folded-block-scalars/000077500000000000000000000000001501576637100350215ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suitein.json000066400000000000000000000001171501576637100363210ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/more-indented-lines-at-the-beginning-of-folded-block-scalars{ "a": " more indented\nregular\n", "b": "\n\n more indented\nregular\n" } in.yaml000066400000000000000000000001101501576637100363030ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/more-indented-lines-at-the-beginning-of-folded-block-scalars--- a: >2 more indented regular b: >2 more indented regular goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multi-level-mapping-indent/000077500000000000000000000000001501576637100267145ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multi-level-mapping-indent/in.json000066400000000000000000000001361501576637100302150ustar00rootroot00000000000000{ "a": { "b": { "c": "d" }, "e": { "f": "g" } }, "h": "i" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multi-level-mapping-indent/in.yaml000066400000000000000000000000441501576637100302040ustar00rootroot00000000000000a: b: c: d e: f: g h: i goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-double-quoted-flow-mapping-key/000077500000000000000000000000001501576637100315025ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-double-quoted-flow-mapping-key/in.json000066400000000000000000000001121501576637100327750ustar00rootroot00000000000000[ { "single line": "value" }, { "multi line": "value" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-double-quoted-flow-mapping-key/in.yaml000066400000000000000000000000711501576637100327720ustar00rootroot00000000000000--- - { "single line": value} - { "multi line": value} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-double-quoted-flow-mapping-key/out.yaml000066400000000000000000000000611501576637100331720ustar00rootroot00000000000000--- - "single line": value - "multi line": value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-double-quoted-implicit-keys/000077500000000000000000000000001501576637100310775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-double-quoted-implicit-keys/error000066400000000000000000000000001501576637100321410ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-double-quoted-implicit-keys/in.yaml000066400000000000000000000000241501576637100323650ustar00rootroot00000000000000"a\nb": 1 "c d": 1 multiline-doublequoted-flow-mapping-key-without-value/000077500000000000000000000000001501576637100341615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suitein.json000066400000000000000000000001401501576637100354550ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-doublequoted-flow-mapping-key-without-value[ { "single line": null, "a": "b" }, { "multi line": null, "a": "b" } ] in.yaml000066400000000000000000000000671501576637100354560ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-doublequoted-flow-mapping-key-without-value--- - { "single line", a: b} - { "multi line", a: b} out.yaml000066400000000000000000000000631501576637100356530ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-doublequoted-flow-mapping-key-without-value--- - "single line": a: b - "multi line": a: b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-implicit-keys/000077500000000000000000000000001501576637100263305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-implicit-keys/error000066400000000000000000000000001501576637100273720ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-implicit-keys/in.yaml000066400000000000000000000000201501576637100276120ustar00rootroot00000000000000a\nb: 1 c d: 1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-flow-mapping-key-without-value/000077500000000000000000000000001501576637100326475ustar00rootroot00000000000000in.json000066400000000000000000000001401501576637100340640ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-flow-mapping-key-without-value[ { "single line": null, "a": "b" }, { "multi line": null, "a": "b" } ] in.yaml000066400000000000000000000000631501576637100340610ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-flow-mapping-key-without-value--- - { single line, a: b} - { multi line, a: b} out.yaml000066400000000000000000000000571501576637100342650ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-flow-mapping-key-without-value--- - single line: a: b - multi line: a: b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-flow-mapping-key/000077500000000000000000000000001501576637100300345ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-flow-mapping-key/in.json000066400000000000000000000001121501576637100313270ustar00rootroot00000000000000[ { "single line": "value" }, { "multi line": "value" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-flow-mapping-key/in.yaml000066400000000000000000000000651501576637100313270ustar00rootroot00000000000000--- - { single line: value} - { multi line: value} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-flow-mapping-key/out.yaml000066400000000000000000000000551501576637100315270ustar00rootroot00000000000000--- - single line: value - multi line: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-scalar-with-empty-line/000077500000000000000000000000001501576637100311455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-scalar-with-empty-line/in.json000066400000000000000000000000301501576637100324370ustar00rootroot00000000000000{ "plain": "a b\nc" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-scalar-with-empty-line/in.yaml000066400000000000000000000000241501576637100324330ustar00rootroot00000000000000--- plain: a b c goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-scalar-with-empty-line/out.yaml000066400000000000000000000000261501576637100326360ustar00rootroot00000000000000--- plain: 'a b c' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-value-with-tabs-on-empty-lines/000077500000000000000000000000001501576637100325405ustar00rootroot00000000000000in.json000066400000000000000000000000401501576637100337540ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-value-with-tabs-on-empty-lines{ "key": "value with\ntabs" } in.yaml000066400000000000000000000000371501576637100337530ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-value-with-tabs-on-empty-lineskey: value with tabs out.yaml000066400000000000000000000000321501576637100341470ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-plain-value-with-tabs-on-empty-lineskey: 'value with tabs' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-at-top-level-1-3/000077500000000000000000000000001501576637100276175ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-at-top-level-1-3/in.json000066400000000000000000000000151501576637100311140ustar00rootroot00000000000000"a b c d\ne" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-at-top-level-1-3/in.yaml000066400000000000000000000000231501576637100311040ustar00rootroot00000000000000--- a b c d e goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-at-top-level-1-3/out.yaml000066400000000000000000000000171501576637100313100ustar00rootroot00000000000000'a b c d e' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-at-top-level/000077500000000000000000000000001501576637100273215ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-at-top-level/in.json000066400000000000000000000000151501576637100306160ustar00rootroot00000000000000"a b c d\ne" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-at-top-level/in.yaml000066400000000000000000000000171501576637100306110ustar00rootroot00000000000000a b c d e goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-at-top-level/out.yaml000066400000000000000000000000171501576637100310120ustar00rootroot00000000000000'a b c d e' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-in-mapping/000077500000000000000000000000001501576637100270475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-in-mapping/in.json000066400000000000000000000000371501576637100303500ustar00rootroot00000000000000{ "a": "b c", "d": "e f" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-in-mapping/in.yaml000066400000000000000000000000221501576637100303330ustar00rootroot00000000000000a: b c d: e f goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-in-mapping/out.yaml000066400000000000000000000000161501576637100305370ustar00rootroot00000000000000a: b c d: e f goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-that-looks-like-a-yaml-directive/000077500000000000000000000000001501576637100331515ustar00rootroot00000000000000in.json000066400000000000000000000000231501576637100343660ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-that-looks-like-a-yaml-directive"scalar %YAML 1.2" in.yaml000066400000000000000000000000251501576637100343610ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-that-looks-like-a-yaml-directive--- scalar %YAML 1.2 out.yaml000066400000000000000000000000311501576637100345570ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-scalar-that-looks-like-a-yaml-directive--- scalar %YAML 1.2 ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-single-quoted-implicit-keys/000077500000000000000000000000001501576637100311065ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-single-quoted-implicit-keys/error000066400000000000000000000000001501576637100321500ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-single-quoted-implicit-keys/in.yaml000066400000000000000000000000241501576637100323740ustar00rootroot00000000000000'a\nb': 1 'c d': 1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-unidented-double-quoted-block-key/000077500000000000000000000000001501576637100321515ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-unidented-double-quoted-block-key/error000066400000000000000000000000001501576637100332130ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiline-unidented-double-quoted-block-key/in.yaml000066400000000000000000000000211501576637100334340ustar00rootroot00000000000000- - "bar bar": x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiple-entry-block-sequence/000077500000000000000000000000001501576637100274355ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiple-entry-block-sequence/in.json000066400000000000000000000000331501576637100307320ustar00rootroot00000000000000[ "foo", "bar", 42 ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiple-entry-block-sequence/in.yaml000066400000000000000000000000211501576637100307200ustar00rootroot00000000000000- foo - bar - 42 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiple-pair-block-mapping/000077500000000000000000000000001501576637100270525ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiple-pair-block-mapping/in.json000066400000000000000000000000661501576637100303550ustar00rootroot00000000000000{ "foo": "blue", "bar": "arrr", "baz": "jazz" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/multiple-pair-block-mapping/in.yaml000066400000000000000000000000361501576637100303430ustar00rootroot00000000000000foo: blue bar: arrr baz: jazz goccy-go-yaml-52dacb8/testdata/yaml-test-suite/need-document-footer-before-directives/000077500000000000000000000000001501576637100311675ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/need-document-footer-before-directives/error000066400000000000000000000000001501576637100322310ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/need-document-footer-before-directives/in.yaml000066400000000000000000000000731501576637100324610ustar00rootroot00000000000000!foo "bar" %TAG ! tag:example.com,2000:app/ --- !foo "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-collections-on-one-line/000077500000000000000000000000001501576637100304265ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-collections-on-one-line/in.json000066400000000000000000000001351501576637100317260ustar00rootroot00000000000000{ "a": [ "b", "c", { "d": [ "e", "f" ] } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-collections-on-one-line/in.yaml000066400000000000000000000000421501576637100317140ustar00rootroot00000000000000--- { a: [b, c, { d: [e, f] } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-collections-on-one-line/out.yaml000066400000000000000000000000401501576637100321130ustar00rootroot00000000000000--- a: - b - c - d: - e - f goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-collections/000077500000000000000000000000001501576637100263105ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-collections/in.json000066400000000000000000000001351501576637100276100ustar00rootroot00000000000000{ "a": [ "b", "c", { "d": [ "e", "f" ] } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-collections/in.yaml000066400000000000000000000000541501576637100276010ustar00rootroot00000000000000--- { a: [ b, c, { d: [e, f] } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-collections/out.yaml000066400000000000000000000000401501576637100277750ustar00rootroot00000000000000--- a: - b - c - d: - e - f goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-mapping-sequence-and-mappings/000077500000000000000000000000001501576637100316075ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-mapping-sequence-and-mappings/in.json000066400000000000000000000001451501576637100331100ustar00rootroot00000000000000{ "top1": [ "item1", { "key2": "value2" }, "item3" ], "top2": "value2" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-mapping-sequence-and-mappings/in.yaml000066400000000000000000000000731501576637100331010ustar00rootroot00000000000000--- { top1: [item1, {key2: value2}, item3], top2: value2 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-flow-mapping-sequence-and-mappings/out.yaml000066400000000000000000000000661501576637100333040ustar00rootroot00000000000000--- top1: - item1 - key2: value2 - item3 top2: value2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-implicit-complex-keys/000077500000000000000000000000001501576637100272555ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-implicit-complex-keys/in.yaml000066400000000000000000000000451501576637100305460ustar00rootroot00000000000000--- [ [ a, [ [[b,c]]: d, e]]: 23 ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-implicit-complex-keys/out.yaml000066400000000000000000000001111501576637100307410ustar00rootroot00000000000000--- - ? - a - - ? - - b - c : d - e : 23 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-top-level-flow-mapping/000077500000000000000000000000001501576637100273325ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-top-level-flow-mapping/in.json000066400000000000000000000000771501576637100306370ustar00rootroot00000000000000{ "key": [ [ [ "value" ] ] ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-top-level-flow-mapping/in.yaml000066400000000000000000000000321501576637100306170ustar00rootroot00000000000000{ key: [[[ value ]]] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/nested-top-level-flow-mapping/out.yaml000066400000000000000000000000211501576637100310160ustar00rootroot00000000000000key: - - - value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-and-tag-on-seperate-lines/000077500000000000000000000000001501576637100306035ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-and-tag-on-seperate-lines/in.json000066400000000000000000000000401501576637100320760ustar00rootroot00000000000000{ "key": { "a": "b" } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-and-tag-on-seperate-lines/in.yaml000066400000000000000000000000331501576637100320710ustar00rootroot00000000000000key: &anchor !!map a: b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-and-tag-on-seperate-lines/out.yaml000066400000000000000000000000321501576637100322710ustar00rootroot00000000000000key: &anchor !!map a: b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-in-sequence/000077500000000000000000000000001501576637100261545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-in-sequence/error000066400000000000000000000000001501576637100272160ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-in-sequence/in.yaml000066400000000000000000000000261501576637100274440ustar00rootroot00000000000000- item1 &node - item2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-not-indented/000077500000000000000000000000001501576637100263305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-not-indented/error000066400000000000000000000000001501576637100273720ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-anchor-not-indented/in.yaml000066400000000000000000000000251501576637100276170ustar00rootroot00000000000000key: &x !!map a: b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-and-mapping-key-anchors-1-3/000077500000000000000000000000001501576637100274025ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-and-mapping-key-anchors-1-3/in.json000066400000000000000000000003321501576637100307010ustar00rootroot00000000000000{ "top1": { "key1": "one" }, "top2": { "key2": "two" }, "top3": { "key3": "three" }, "top4": { "key4": "four" }, "top5": { "key5": "five" }, "top6": "six", "top7": "seven" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-and-mapping-key-anchors-1-3/in.yaml000066400000000000000000000002721501576637100306750ustar00rootroot00000000000000--- top1: &node1 &k1 key1: one top2: &node2 # comment key2: two top3: &k3 key3: three top4: &node4 &k4 key4: four top5: &node5 key5: five top6: &val6 six top7: &val7 seven goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-and-mapping-key-anchors-1-3/out.yaml000066400000000000000000000002541501576637100310760ustar00rootroot00000000000000--- top1: &node1 &k1 key1: one top2: &node2 key2: two top3: &k3 key3: three top4: &node4 &k4 key4: four top5: &node5 key5: five top6: &val6 six top7: &val7 seven goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-and-mapping-key-anchors/000077500000000000000000000000001501576637100271045ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-and-mapping-key-anchors/in.json000066400000000000000000000003321501576637100304030ustar00rootroot00000000000000{ "top1": { "key1": "one" }, "top2": { "key2": "two" }, "top3": { "key3": "three" }, "top4": { "key4": "four" }, "top5": { "key5": "five" }, "top6": "six", "top7": "seven" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-and-mapping-key-anchors/in.yaml000066400000000000000000000002761501576637100304030ustar00rootroot00000000000000--- top1: &node1 &k1 key1: one top2: &node2 # comment key2: two top3: &k3 key3: three top4: &node4 &k4 key4: four top5: &node5 key5: five top6: &val6 six top7: &val7 seven goccy-go-yaml-52dacb8/testdata/yaml-test-suite/node-and-mapping-key-anchors/out.yaml000066400000000000000000000002541501576637100306000ustar00rootroot00000000000000--- top1: &node1 &k1 key1: one top2: &node2 key2: two top3: &k3 key3: three top4: &node4 &k4 key4: four top5: &node5 key5: five top6: &val6 six top7: &val7 seven goccy-go-yaml-52dacb8/testdata/yaml-test-suite/non-specific-tags-on-scalars/000077500000000000000000000000001501576637100271165ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/non-specific-tags-on-scalars/in.json000066400000000000000000000001221501576637100304120ustar00rootroot00000000000000[ "plain", "double quoted", "single quoted", "block\n", "plain again" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/non-specific-tags-on-scalars/in.yaml000066400000000000000000000001061501576637100304050ustar00rootroot00000000000000- plain - "double quoted" - 'single quoted' - > block - plain again goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-dashes-in-flow-sequence/000077500000000000000000000000001501576637100272745ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-dashes-in-flow-sequence/error000066400000000000000000000000001501576637100303360ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-dashes-in-flow-sequence/in.yaml000066400000000000000000000000151501576637100305620ustar00rootroot00000000000000--- - [-, -] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-mapping-key-ending-with-colon/000077500000000000000000000000001501576637100304125ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-mapping-key-ending-with-colon/in.json000066400000000000000000000000541501576637100317120ustar00rootroot00000000000000{ "key ends with two colons::": "value" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-mapping-key-ending-with-colon/in.yaml000066400000000000000000000000461501576637100317040ustar00rootroot00000000000000--- key ends with two colons::: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-mapping-key-ending-with-colon/out.yaml000066400000000000000000000000501501576637100321000ustar00rootroot00000000000000--- 'key ends with two colons::': value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-scalar-looking-like-key-comment-anchor-and-tag/000077500000000000000000000000001501576637100335045ustar00rootroot00000000000000in.json000066400000000000000000000000211501576637100347170ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-scalar-looking-like-key-comment-anchor-and-tag"k:#foo &a !t s" in.yaml000066400000000000000000000000241501576637100347130ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-scalar-looking-like-key-comment-anchor-and-tag--- k:#foo &a !t s out.yaml000066400000000000000000000000231501576637100351130ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-scalar-looking-like-key-comment-anchor-and-tag--- k:#foo &a !t s goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-scalar-with-backslashes/000077500000000000000000000000001501576637100273455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-scalar-with-backslashes/in.json000066400000000000000000000000421501576637100306420ustar00rootroot00000000000000"plain\\value\\with\\backslashes" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-scalar-with-backslashes/in.yaml000066400000000000000000000000411501576637100306320ustar00rootroot00000000000000--- plain\value\with\backslashes goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-scalar-with-backslashes/out.yaml000066400000000000000000000000411501576637100310330ustar00rootroot00000000000000--- plain\value\with\backslashes goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-url-in-flow-mapping/000077500000000000000000000000001501576637100264525ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-url-in-flow-mapping/in.json000066400000000000000000000000541501576637100277520ustar00rootroot00000000000000[ { "url": "http://example.org" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-url-in-flow-mapping/in.yaml000066400000000000000000000000361501576637100277430ustar00rootroot00000000000000- { url: http://example.org } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/plain-url-in-flow-mapping/out.yaml000066400000000000000000000000321501576637100301400ustar00rootroot00000000000000- url: http://example.org goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-at-start-of-flow-key/000077500000000000000000000000001501576637100302365ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-at-start-of-flow-key/in.json000066400000000000000000000000431501576637100315340ustar00rootroot00000000000000{ "?foo" : "bar", "bar" : 42 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-at-start-of-flow-key/in.yaml000066400000000000000000000000271501576637100315270ustar00rootroot00000000000000{ ?foo: bar, bar: 42 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-at-start-of-flow-key/out.yaml000066400000000000000000000000261501576637100317270ustar00rootroot00000000000000--- ?foo: bar bar: 42 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-edge-cases/000077500000000000000000000000001501576637100263425ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-edge-cases/00/000077500000000000000000000000001501576637100265615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-edge-cases/00/in.yaml000066400000000000000000000000101501576637100300420ustar00rootroot00000000000000- ? : x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-edge-cases/00/out.yaml000066400000000000000000000000141501576637100302470ustar00rootroot00000000000000- ? : x : goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-edge-cases/01/000077500000000000000000000000001501576637100265625ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-edge-cases/01/in.yaml000066400000000000000000000000101501576637100300430ustar00rootroot00000000000000? []: x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-mark-edge-cases/01/out.yaml000066400000000000000000000000121501576637100302460ustar00rootroot00000000000000? []: x : goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-marks-in-scalars/000077500000000000000000000000001501576637100265615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-marks-in-scalars/in.json000066400000000000000000000003231501576637100300600ustar00rootroot00000000000000[ "a?string", "another ? string", { "key": "value?" }, [ "a?string" ], [ "another ? string" ], { "key": "value?" }, { "key": "value?" }, { "key?": "value" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-marks-in-scalars/in.yaml000066400000000000000000000002001501576637100300430ustar00rootroot00000000000000- a?string - another ? string - key: value? - [a?string] - [another ? string] - {key: value? } - {key: value?} - {key?: value } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/question-marks-in-scalars/out.yaml000066400000000000000000000001701501576637100302520ustar00rootroot00000000000000- a?string - another ? string - key: value? - - a?string - - another ? string - key: value? - key: value? - key?: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-doc-with-in-content/000077500000000000000000000000001501576637100266025ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-doc-with-in-content/00/000077500000000000000000000000001501576637100270215ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-doc-with-in-content/00/in.json000066400000000000000000000000131501576637100303140ustar00rootroot00000000000000"a ...x b" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-doc-with-in-content/00/in.yaml000066400000000000000000000000171501576637100303110ustar00rootroot00000000000000--- "a ...x b" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-doc-with-in-content/00/out.yaml000066400000000000000000000000151501576637100305100ustar00rootroot00000000000000--- a ...x b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-doc-with-in-content/01/000077500000000000000000000000001501576637100270225ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-doc-with-in-content/01/error000066400000000000000000000000001501576637100300640ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-doc-with-in-content/01/in.json000066400000000000000000000000131501576637100303150ustar00rootroot00000000000000"a ...x b" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-doc-with-in-content/01/in.yaml000066400000000000000000000000201501576637100303040ustar00rootroot00000000000000--- "a ... x b" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-value-with-two-anchors/000077500000000000000000000000001501576637100273375ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-value-with-two-anchors/error000066400000000000000000000000001501576637100304010ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalar-value-with-two-anchors/in.yaml000066400000000000000000000000661501576637100306330ustar00rootroot00000000000000top1: &node1 &k1 key1: val1 top2: &node2 &v2 val2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-in-flow-start-with-syntax-char/000077500000000000000000000000001501576637100311115ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-in-flow-start-with-syntax-char/00/000077500000000000000000000000001501576637100313305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-in-flow-start-with-syntax-char/00/in.json000066400000000000000000000000131501576637100326230ustar00rootroot00000000000000[ ":x" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-in-flow-start-with-syntax-char/00/in.yaml000066400000000000000000000000051501576637100326150ustar00rootroot00000000000000[:x] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-in-flow-start-with-syntax-char/00/out.yaml000066400000000000000000000000051501576637100330160ustar00rootroot00000000000000- :x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-in-flow-start-with-syntax-char/01/000077500000000000000000000000001501576637100313315ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-in-flow-start-with-syntax-char/01/in.json000066400000000000000000000000131501576637100326240ustar00rootroot00000000000000[ "?x" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-in-flow-start-with-syntax-char/01/in.yaml000066400000000000000000000000051501576637100326160ustar00rootroot00000000000000[?x] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-in-flow-start-with-syntax-char/01/out.yaml000066400000000000000000000000051501576637100330170ustar00rootroot00000000000000- ?x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-on-line/000077500000000000000000000000001501576637100245345ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-on-line/in.json000066400000000000000000000000261501576637100260330ustar00rootroot00000000000000"quoted string" "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-on-line/in.yaml000066400000000000000000000000421501576637100260220ustar00rootroot00000000000000--- "quoted string" --- &node foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/scalars-on-line/out.yaml000066400000000000000000000000461501576637100262270ustar00rootroot00000000000000--- "quoted string" --- &node foo ... sequence-entry-that-looks-like-two-with-wrong-indentation/000077500000000000000000000000001501576637100346665ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suitein.json000066400000000000000000000000521501576637100361640ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-entry-that-looks-like-two-with-wrong-indentation[ "single multiline - sequence entry" ] in.yaml000066400000000000000000000000451501576637100361570ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-entry-that-looks-like-two-with-wrong-indentation- single multiline - sequence entry out.yaml000066400000000000000000000000441501576637100363570ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-entry-that-looks-like-two-with-wrong-indentation- single multiline - sequence entry goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-indent/000077500000000000000000000000001501576637100246345ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-indent/in.json000066400000000000000000000000611501576637100261320ustar00rootroot00000000000000{ "foo": [ 42 ], "bar": [ 44 ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-indent/in.yaml000066400000000000000000000000261501576637100261240ustar00rootroot00000000000000foo: - 42 bar: - 44 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-indent/out.yaml000066400000000000000000000000241501576637100263230ustar00rootroot00000000000000foo: - 42 bar: - 44 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-on-same-line-as-mapping-key/000077500000000000000000000000001501576637100304575ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-on-same-line-as-mapping-key/error000066400000000000000000000000001501576637100315210ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-on-same-line-as-mapping-key/in.yaml000066400000000000000000000000221501576637100317430ustar00rootroot00000000000000key: - a - b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-with-same-indentation-as-parent-mapping/000077500000000000000000000000001501576637100331045ustar00rootroot00000000000000in.json000066400000000000000000000000551501576637100343260ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-with-same-indentation-as-parent-mapping{ "one": [ 2, 3 ], "four": 5 } in.yaml000066400000000000000000000000251501576637100343140ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/sequence-with-same-indentation-as-parent-mappingone: - 2 - 3 four: 5 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/simple-mapping-indent/000077500000000000000000000000001501576637100257465ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/simple-mapping-indent/in.json000066400000000000000000000000441501576637100272450ustar00rootroot00000000000000{ "foo": { "bar": "baz" } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/simple-mapping-indent/in.yaml000066400000000000000000000000201501576637100272300ustar00rootroot00000000000000foo: bar: baz single-block-sequence-with-anchor-and-explicit-document-start/000077500000000000000000000000001501576637100354145ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suitein.json000066400000000000000000000000121501576637100367060ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-block-sequence-with-anchor-and-explicit-document-start[ "a" ] in.yaml000066400000000000000000000000221501576637100367000ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-block-sequence-with-anchor-and-explicit-document-start--- &sequence - a out.yaml000066400000000000000000000000221501576637100371010ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-block-sequence-with-anchor-and-explicit-document-start--- &sequence - a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-block-sequence-with-anchor/000077500000000000000000000000001501576637100301455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-block-sequence-with-anchor/in.json000066400000000000000000000000121501576637100314370ustar00rootroot00000000000000[ "a" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-block-sequence-with-anchor/in.yaml000066400000000000000000000000161501576637100314340ustar00rootroot00000000000000&sequence - a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-block-sequence-with-anchor/out.yaml000066400000000000000000000000161501576637100316350ustar00rootroot00000000000000&sequence - a goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-character-streams/000077500000000000000000000000001501576637100264345ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-character-streams/00/000077500000000000000000000000001501576637100266535ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-character-streams/00/in.json000066400000000000000000000000071501576637100301510ustar00rootroot00000000000000[null] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-character-streams/00/in.yaml000066400000000000000000000000011501576637100301340ustar00rootroot00000000000000-goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-character-streams/00/out.yaml000066400000000000000000000000021501576637100303360ustar00rootroot00000000000000- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-character-streams/01/000077500000000000000000000000001501576637100266545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-character-streams/01/in.yaml000066400000000000000000000000011501576637100301350ustar00rootroot00000000000000:goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-character-streams/01/out.yaml000066400000000000000000000000021501576637100303370ustar00rootroot00000000000000: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-entry-block-sequence/000077500000000000000000000000001501576637100270635ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-entry-block-sequence/in.json000066400000000000000000000000141501576637100303570ustar00rootroot00000000000000[ "foo" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-entry-block-sequence/in.yaml000066400000000000000000000000061501576637100303510ustar00rootroot00000000000000- foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-pair-block-mapping/000077500000000000000000000000001501576637100265005ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-pair-block-mapping/in.json000066400000000000000000000000231501576637100277740ustar00rootroot00000000000000{ "foo": "bar" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-pair-block-mapping/in.yaml000066400000000000000000000000111501576637100277620ustar00rootroot00000000000000foo: bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-pair-implicit-entries/000077500000000000000000000000001501576637100272365ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-pair-implicit-entries/in.yaml000066400000000000000000000001151501576637100305250ustar00rootroot00000000000000- [ YAML : separate ] - [ "JSON like":adjacent ] - [ {JSON: like}:adjacent ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/single-pair-implicit-entries/out.yaml000066400000000000000000000001151501576637100307260ustar00rootroot00000000000000- - YAML: separate - - "JSON like": adjacent - - ? JSON: like : adjacent goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-1-sequence-of-scalars/000077500000000000000000000000001501576637100302635ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-1-sequence-of-scalars/in.json000066400000000000000000000000661501576637100315660ustar00rootroot00000000000000[ "Mark McGwire", "Sammy Sosa", "Ken Griffey" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-1-sequence-of-scalars/in.yaml000066400000000000000000000000521501576637100315520ustar00rootroot00000000000000- Mark McGwire - Sammy Sosa - Ken Griffey goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-1-sequence-of-scalars/lex.token000066400000000000000000000002511501576637100321130ustar00rootroot00000000000000SEQ-MARK 0 1 1 1 WS-SPACE 1 1 1 2 TEXT-VAL 2 12 1 3 :Mark McGwire WS-NEWLN 14 1 1 15 SEQ-MARK 15 1 2 1 WS-SPACE 1 1 1 2 TEXT-VAL 2 12 1 3 :Sammy Sosa WS-NEWLN 14 1 1 15 spec-example-2-10-node-for-sammy-sosa-appears-twice-in-this-document/000077500000000000000000000000001501576637100361535ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suitein.json000066400000000000000000000001531501576637100374530ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-10-node-for-sammy-sosa-appears-twice-in-this-document{ "hr": [ "Mark McGwire", "Sammy Sosa" ], "rbi": [ "Sammy Sosa", "Ken Griffey" ] } in.yaml000066400000000000000000000001771501576637100374520ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-10-node-for-sammy-sosa-appears-twice-in-this-document--- hr: - Mark McGwire # Following node labeled SS - &SS Sammy Sosa rbi: - *SS # Subsequent occurrence - Ken Griffey out.yaml000066400000000000000000000001011501576637100376360ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-10-node-for-sammy-sosa-appears-twice-in-this-document--- hr: - Mark McGwire - &SS Sammy Sosa rbi: - *SS - Ken Griffey goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-11-mapping-between-sequences/000077500000000000000000000000001501576637100315575ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-11-mapping-between-sequences/in.yaml000066400000000000000000000002161501576637100330500ustar00rootroot00000000000000? - Detroit Tigers - Chicago cubs : - 2001-07-23 ? [ New York Yankees, Atlanta Braves ] : [ 2001-07-02, 2001-08-12, 2001-08-14 ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-11-mapping-between-sequences/out.yaml000066400000000000000000000002101501576637100332430ustar00rootroot00000000000000? - Detroit Tigers - Chicago cubs : - 2001-07-23 ? - New York Yankees - Atlanta Braves : - 2001-07-02 - 2001-08-12 - 2001-08-14 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-12-compact-nested-mapping/000077500000000000000000000000001501576637100310445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-12-compact-nested-mapping/in.json000066400000000000000000000002411501576637100323420ustar00rootroot00000000000000[ { "item": "Super Hoop", "quantity": 1 }, { "item": "Basketball", "quantity": 4 }, { "item": "Big Shoes", "quantity": 1 } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-12-compact-nested-mapping/in.yaml000066400000000000000000000002071501576637100323350ustar00rootroot00000000000000--- # Products purchased - item : Super Hoop quantity: 1 - item : Basketball quantity: 4 - item : Big Shoes quantity: 1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-12-compact-nested-mapping/out.yaml000066400000000000000000000001461501576637100325400ustar00rootroot00000000000000--- - item: Super Hoop quantity: 1 - item: Basketball quantity: 4 - item: Big Shoes quantity: 1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-13-in-literals-newlines-are-preserved/000077500000000000000000000000001501576637100333155ustar00rootroot00000000000000in.json000066400000000000000000000000351501576637100345350ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-13-in-literals-newlines-are-preserved"\\//||\\/||\n// || ||__\n" in.yaml000066400000000000000000000000541501576637100345270ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-13-in-literals-newlines-are-preserved# ASCII Art --- | \//||\/|| // || ||__ out.yaml000066400000000000000000000000401501576637100347230ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-13-in-literals-newlines-are-preserved--- | \//||\/|| // || ||__ spec-example-2-14-in-the-folded-scalars-newlines-become-spaces/000077500000000000000000000000001501576637100350235ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suitein.json000066400000000000000000000000671501576637100363270ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-14-in-the-folded-scalars-newlines-become-spaces"Mark McGwire's year was crippled by a knee injury.\n" in.yaml000066400000000000000000000000771501576637100363210ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-14-in-the-folded-scalars-newlines-become-spaces--- > Mark McGwire's year was crippled by a knee injury. out.yaml000066400000000000000000000000731501576637100365160ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-14-in-the-folded-scalars-newlines-become-spaces--- > Mark McGwire's year was crippled by a knee injury. spec-example-2-15-folded-newlines-are-preserved-for-more-indented-and-blank-lines/000077500000000000000000000000001501576637100405235ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suitein.json000066400000000000000000000001721501576637100420240ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-15-folded-newlines-are-preserved-for-more-indented-and-blank-lines"Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" in.yaml000066400000000000000000000001701501576637100420130ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-15-folded-newlines-are-preserved-for-more-indented-and-blank-lines> Sammy Sosa completed another fine season with great stats. 63 Home Runs 0.288 Batting Average What a year! out.yaml000066400000000000000000000001731501576637100422170ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-15-folded-newlines-are-preserved-for-more-indented-and-blank-lines> Sammy Sosa completed another fine season with great stats. 63 Home Runs 0.288 Batting Average What a year! goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-16-indentation-determines-scope/000077500000000000000000000000001501576637100322715ustar00rootroot00000000000000in.json000066400000000000000000000002331501576637100335110ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-16-indentation-determines-scope{ "name": "Mark McGwire", "accomplishment": "Mark set a major league home run record in 1998.\n", "stats": "65 Home Runs\n0.278 Batting Average\n" } in.yaml000066400000000000000000000002121501576637100334770ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-16-indentation-determines-scopename: Mark McGwire accomplishment: > Mark set a major league home run record in 1998. stats: | 65 Home Runs 0.278 Batting Average out.yaml000066400000000000000000000002101501576637100336760ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-16-indentation-determines-scopename: Mark McGwire accomplishment: > Mark set a major league home run record in 1998. stats: | 65 Home Runs 0.278 Batting Average goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-17-quoted-scalars/000077500000000000000000000000001501576637100274415ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-17-quoted-scalars/in.json000066400000000000000000000003131501576637100307370ustar00rootroot00000000000000{ "unicode": "Sosa did fine.☺", "control": "\b1998\t1999\t2000\n", "hex esc": "\r\n is \r\n", "single": "\"Howdy!\" he cried.", "quoted": " # Not a 'comment'.", "tie-fighter": "|\\-*-/|" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-17-quoted-scalars/in.yaml000066400000000000000000000002611501576637100307320ustar00rootroot00000000000000unicode: "Sosa did fine.\u263A" control: "\b1998\t1999\t2000\n" hex esc: "\x0d\x0a is \r\n" single: '"Howdy!" he cried.' quoted: ' # Not a ''comment''.' tie-fighter: '|\-*-/|' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-17-quoted-scalars/out.yaml000066400000000000000000000002541501576637100311350ustar00rootroot00000000000000unicode: "Sosa did fine.\u263A" control: "\b1998\t1999\t2000\n" hex esc: "\r\n is \r\n" single: '"Howdy!" he cried.' quoted: ' # Not a ''comment''.' tie-fighter: '|\-*-/|' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-18-multi-line-flow-scalars/000077500000000000000000000000001501576637100311655ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-18-multi-line-flow-scalars/in.json000066400000000000000000000001451501576637100324660ustar00rootroot00000000000000{ "plain": "This unquoted scalar spans many lines.", "quoted": "So does this quoted scalar.\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-18-multi-line-flow-scalars/in.yaml000066400000000000000000000001351501576637100324560ustar00rootroot00000000000000plain: This unquoted scalar spans many lines. quoted: "So does this quoted scalar.\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-18-multi-line-flow-scalars/out.yaml000066400000000000000000000001261501576637100326570ustar00rootroot00000000000000plain: This unquoted scalar spans many lines. quoted: "So does this quoted scalar.\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-2-mapping-scalars-to-scalars/000077500000000000000000000000001501576637100315535ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-2-mapping-scalars-to-scalars/in.json000066400000000000000000000000551501576637100330540ustar00rootroot00000000000000{ "hr": 65, "avg": 0.278, "rbi": 147 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-2-mapping-scalars-to-scalars/in.yaml000066400000000000000000000001201501576637100330360ustar00rootroot00000000000000hr: 65 # Home runs avg: 0.278 # Batting average rbi: 147 # Runs Batted In goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-2-mapping-scalars-to-scalars/out.yaml000066400000000000000000000000331501576637100332420ustar00rootroot00000000000000hr: 65 avg: 0.278 rbi: 147 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-24-global-tags/000077500000000000000000000000001501576637100267045ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-24-global-tags/in.json000066400000000000000000000004731501576637100302110ustar00rootroot00000000000000[ { "center": { "x": 73, "y": 129 }, "radius": 7 }, { "start": { "x": 73, "y": 129 }, "finish": { "x": 89, "y": 102 } }, { "start": { "x": 73, "y": 129 }, "color": 16772795, "text": "Pretty vector drawing." } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-24-global-tags/in.yaml000066400000000000000000000004521501576637100301770ustar00rootroot00000000000000%TAG ! tag:clarkevans.com,2002: --- !shape # Use the ! handle for presenting # tag:clarkevans.com,2002:circle - !circle center: &ORIGIN {x: 73, y: 129} radius: 7 - !line start: *ORIGIN finish: { x: 89, y: 102 } - !label start: *ORIGIN color: 0xFFEEBB text: Pretty vector drawing. goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-24-global-tags/out.yaml000066400000000000000000000004631501576637100304020ustar00rootroot00000000000000--- ! - ! center: &ORIGIN x: 73 y: 129 radius: 7 - ! start: *ORIGIN finish: x: 89 y: 102 - ! start: *ORIGIN color: 0xFFEEBB text: Pretty vector drawing. goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-25-unordered-sets/000077500000000000000000000000001501576637100274545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-25-unordered-sets/in.json000066400000000000000000000001061501576637100307520ustar00rootroot00000000000000{ "Mark McGwire": null, "Sammy Sosa": null, "Ken Griff": null } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-25-unordered-sets/in.yaml000066400000000000000000000002111501576637100307400ustar00rootroot00000000000000# Sets are represented as a # Mapping where each key is # associated with a null value --- !!set ? Mark McGwire ? Sammy Sosa ? Ken Griff goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-25-unordered-sets/out.yaml000066400000000000000000000000571501576637100311510ustar00rootroot00000000000000--- !!set Mark McGwire: Sammy Sosa: Ken Griff: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-26-ordered-mappings/000077500000000000000000000000001501576637100277525ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-26-ordered-mappings/in.json000066400000000000000000000001371501576637100312540ustar00rootroot00000000000000[ { "Mark McGwire": 65 }, { "Sammy Sosa": 63 }, { "Ken Griffy": 58 } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-26-ordered-mappings/in.yaml000066400000000000000000000004761501576637100312530ustar00rootroot00000000000000# The !!omap tag is one of the optional types # introduced for YAML 1.1. In 1.2, it is not # part of the standard tags and should not be # enabled by default. # Ordered maps are represented as # A sequence of mappings, with # each mapping having one key --- !!omap - Mark McGwire: 65 - Sammy Sosa: 63 - Ken Griffy: 58 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-26-ordered-mappings/out.yaml000066400000000000000000000001001501576637100314340ustar00rootroot00000000000000--- !!omap - Mark McGwire: 65 - Sammy Sosa: 63 - Ken Griffy: 58 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-27-invoice/000077500000000000000000000000001501576637100261475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-27-invoice/in.json000066400000000000000000000014731501576637100274550ustar00rootroot00000000000000{ "invoice": 34843, "date": "2001-01-23", "bill-to": { "given": "Chris", "family": "Dumars", "address": { "lines": "458 Walkman Dr.\nSuite #292\n", "city": "Royal Oak", "state": "MI", "postal": 48046 } }, "ship-to": { "given": "Chris", "family": "Dumars", "address": { "lines": "458 Walkman Dr.\nSuite #292\n", "city": "Royal Oak", "state": "MI", "postal": 48046 } }, "product": [ { "sku": "BL394D", "quantity": 4, "description": "Basketball", "price": 450 }, { "sku": "BL4438H", "quantity": 1, "description": "Super Hoop", "price": 2392 } ], "tax": 251.42, "total": 4443.52, "comments": "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338." } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-27-invoice/in.yaml000066400000000000000000000012041501576637100274360ustar00rootroot00000000000000--- ! invoice: 34843 date : 2001-01-23 bill-to: &id001 given : Chris family : Dumars address: lines: | 458 Walkman Dr. Suite #292 city : Royal Oak state : MI postal : 48046 ship-to: *id001 product: - sku : BL394D quantity : 4 description : Basketball price : 450.00 - sku : BL4438H quantity : 1 description : Super Hoop price : 2392.00 tax : 251.42 total: 4443.52 comments: Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-27-invoice/out.yaml000066400000000000000000000007731501576637100276510ustar00rootroot00000000000000--- ! invoice: 34843 date: 2001-01-23 bill-to: &id001 given: Chris family: Dumars address: lines: | 458 Walkman Dr. Suite #292 city: Royal Oak state: MI postal: 48046 ship-to: *id001 product: - sku: BL394D quantity: 4 description: Basketball price: 450.00 - sku: BL4438H quantity: 1 description: Super Hoop price: 2392.00 tax: 251.42 total: 4443.52 comments: Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338. goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-28-log-file/000077500000000000000000000000001501576637100262125ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-28-log-file/in.json000066400000000000000000000010131501576637100275060ustar00rootroot00000000000000{ "Time": "2001-11-23 15:01:42 -5", "User": "ed", "Warning": "This is an error message for the log file" } { "Time": "2001-11-23 15:02:31 -5", "User": "ed", "Warning": "A slightly different error message." } { "Date": "2001-11-23 15:03:17 -5", "User": "ed", "Fatal": "Unknown variable \"bar\"", "Stack": [ { "file": "TopClass.py", "line": 23, "code": "x = MoreObject(\"345\\n\")\n" }, { "file": "MoreClass.py", "line": 58, "code": "foo = bar" } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-28-log-file/in.yaml000066400000000000000000000006331501576637100275060ustar00rootroot00000000000000--- Time: 2001-11-23 15:01:42 -5 User: ed Warning: This is an error message for the log file --- Time: 2001-11-23 15:02:31 -5 User: ed Warning: A slightly different error message. --- Date: 2001-11-23 15:03:17 -5 User: ed Fatal: Unknown variable "bar" Stack: - file: TopClass.py line: 23 code: | x = MoreObject("345\n") - file: MoreClass.py line: 58 code: |- foo = bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-28-log-file/out.yaml000066400000000000000000000006011501576637100277020ustar00rootroot00000000000000--- Time: 2001-11-23 15:01:42 -5 User: ed Warning: This is an error message for the log file --- Time: 2001-11-23 15:02:31 -5 User: ed Warning: A slightly different error message. --- Date: 2001-11-23 15:03:17 -5 User: ed Fatal: Unknown variable "bar" Stack: - file: TopClass.py line: 23 code: | x = MoreObject("345\n") - file: MoreClass.py line: 58 code: |- foo = bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-3-mapping-scalars-to-sequences/000077500000000000000000000000001501576637100321175ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-3-mapping-scalars-to-sequences/in.json000066400000000000000000000002561501576637100334230ustar00rootroot00000000000000{ "american": [ "Boston Red Sox", "Detroit Tigers", "New York Yankees" ], "national": [ "New York Mets", "Chicago Cubs", "Atlanta Braves" ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-3-mapping-scalars-to-sequences/in.yaml000066400000000000000000000002051501576637100334060ustar00rootroot00000000000000american: - Boston Red Sox - Detroit Tigers - New York Yankees national: - New York Mets - Chicago Cubs - Atlanta Braves out.yaml000066400000000000000000000001711501576637100335320ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-3-mapping-scalars-to-sequencesamerican: - Boston Red Sox - Detroit Tigers - New York Yankees national: - New York Mets - Chicago Cubs - Atlanta Braves goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-4-sequence-of-mappings/000077500000000000000000000000001501576637100304545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-4-sequence-of-mappings/in.json000066400000000000000000000002111501576637100317470ustar00rootroot00000000000000[ { "name": "Mark McGwire", "hr": 65, "avg": 0.278 }, { "name": "Sammy Sosa", "hr": 63, "avg": 0.288 } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-4-sequence-of-mappings/in.yaml000066400000000000000000000001361501576637100317460ustar00rootroot00000000000000- name: Mark McGwire hr: 65 avg: 0.278 - name: Sammy Sosa hr: 63 avg: 0.288 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-4-sequence-of-mappings/out.yaml000066400000000000000000000001241501576637100321440ustar00rootroot00000000000000- name: Mark McGwire hr: 65 avg: 0.278 - name: Sammy Sosa hr: 63 avg: 0.288 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-5-sequence-of-sequences/000077500000000000000000000000001501576637100306325ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-5-sequence-of-sequences/in.json000066400000000000000000000002101501576637100321240ustar00rootroot00000000000000[ [ "name", "hr", "avg" ], [ "Mark McGwire", 65, 0.278 ], [ "Sammy Sosa", 63, 0.288 ] ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-5-sequence-of-sequences/in.yaml000066400000000000000000000001241501576637100321210ustar00rootroot00000000000000- [name , hr, avg ] - [Mark McGwire, 65, 0.278] - [Sammy Sosa , 63, 0.288] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-5-sequence-of-sequences/out.yaml000066400000000000000000000001321501576637100323210ustar00rootroot00000000000000- - name - hr - avg - - Mark McGwire - 65 - 0.278 - - Sammy Sosa - 63 - 0.288 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-6-mapping-of-mappings/000077500000000000000000000000001501576637100303015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-6-mapping-of-mappings/in.json000066400000000000000000000001611501576637100316000ustar00rootroot00000000000000{ "Mark McGwire": { "hr": 65, "avg": 0.278 }, "Sammy Sosa": { "hr": 63, "avg": 0.288 } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-6-mapping-of-mappings/in.yaml000066400000000000000000000001201501576637100315640ustar00rootroot00000000000000Mark McGwire: {hr: 65, avg: 0.278} Sammy Sosa: { hr: 63, avg: 0.288 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-6-mapping-of-mappings/out.yaml000066400000000000000000000001061501576637100317710ustar00rootroot00000000000000Mark McGwire: hr: 65 avg: 0.278 Sammy Sosa: hr: 63 avg: 0.288 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-7-two-documents-in-a-stream/000077500000000000000000000000001501576637100313545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-7-two-documents-in-a-stream/in.json000066400000000000000000000001431501576637100326530ustar00rootroot00000000000000[ "Mark McGwire", "Sammy Sosa", "Ken Griffey" ] [ "Chicago Cubs", "St Louis Cardinals" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-7-two-documents-in-a-stream/in.yaml000066400000000000000000000002021501576637100326400ustar00rootroot00000000000000# Ranking of 1998 home runs --- - Mark McGwire - Sammy Sosa - Ken Griffey # Team ranking --- - Chicago Cubs - St Louis Cardinals goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-7-two-documents-in-a-stream/out.yaml000066400000000000000000000001261501576637100330460ustar00rootroot00000000000000--- - Mark McGwire - Sammy Sosa - Ken Griffey --- - Chicago Cubs - St Louis Cardinals goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-8-play-by-play-feed-from-a-game/000077500000000000000000000000001501576637100317415ustar00rootroot00000000000000in.json000066400000000000000000000002351501576637100331630ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-8-play-by-play-feed-from-a-game{ "time": "20:03:20", "player": "Sammy Sosa", "action": "strike (miss)" } { "time": "20:03:47", "player": "Sammy Sosa", "action": "grand slam" } in.yaml000066400000000000000000000001751501576637100331570ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-8-play-by-play-feed-from-a-game--- time: 20:03:20 player: Sammy Sosa action: strike (miss) ... --- time: 20:03:47 player: Sammy Sosa action: grand slam ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-9-single-document-with-two-comments/000077500000000000000000000000001501576637100331335ustar00rootroot00000000000000in.json000066400000000000000000000001531501576637100343540ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-9-single-document-with-two-comments{ "hr": [ "Mark McGwire", "Sammy Sosa" ], "rbi": [ "Sammy Sosa", "Ken Griffey" ] } in.yaml000066400000000000000000000001631501576637100343460ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-9-single-document-with-two-comments--- hr: # 1998 hr ranking - Mark McGwire - Sammy Sosa rbi: # 1998 rbi ranking - Sammy Sosa - Ken Griffey out.yaml000066400000000000000000000001041501576637100345420ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-2-9-single-document-with-two-comments--- hr: - Mark McGwire - Sammy Sosa rbi: - Sammy Sosa - Ken Griffey goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-12-tabs-and-spaces/000077500000000000000000000000001501576637100274555ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-12-tabs-and-spaces/in.json000066400000000000000000000001361501576637100307560ustar00rootroot00000000000000{ "quoted": "Quoted \t", "block": "void main() {\n\tprintf(\"Hello, world!\\n\");\n}\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-12-tabs-and-spaces/in.yaml000066400000000000000000000001401501576637100307420ustar00rootroot00000000000000# Tabs and spaces quoted: "Quoted " block: | void main() { printf("Hello, world!\n"); } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-12-tabs-and-spaces/out.yaml000066400000000000000000000001171501576637100311470ustar00rootroot00000000000000quoted: "Quoted \t" block: | void main() { printf("Hello, world!\n"); } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-3-block-structure-indicators/000077500000000000000000000000001501576637100317155ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-3-block-structure-indicators/in.json000066400000000000000000000001471501576637100332200ustar00rootroot00000000000000{ "sequence": [ "one", "two" ], "mapping": { "sky": "blue", "sea": "green" } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-3-block-structure-indicators/in.yaml000066400000000000000000000000761501576637100332120ustar00rootroot00000000000000sequence: - one - two mapping: ? sky : blue sea : green goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-3-block-structure-indicators/out.yaml000066400000000000000000000000701501576637100334050ustar00rootroot00000000000000sequence: - one - two mapping: sky: blue sea: green goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-4-flow-collection-indicators/000077500000000000000000000000001501576637100316665ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-4-flow-collection-indicators/in.json000066400000000000000000000001471501576637100331710ustar00rootroot00000000000000{ "sequence": [ "one", "two" ], "mapping": { "sky": "blue", "sea": "green" } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-4-flow-collection-indicators/in.yaml000066400000000000000000000000731501576637100331600ustar00rootroot00000000000000sequence: [ one, two, ] mapping: { sky: blue, sea: green } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-4-flow-collection-indicators/out.yaml000066400000000000000000000000701501576637100333560ustar00rootroot00000000000000sequence: - one - two mapping: sky: blue sea: green goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-5-comment-indicator/000077500000000000000000000000001501576637100300465ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-5-comment-indicator/in.json000066400000000000000000000000001501576637100313350ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-5-comment-indicator/in.yaml000066400000000000000000000000201501576637100313300ustar00rootroot00000000000000# Comment only. goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-5-comment-indicator/out.yaml000066400000000000000000000000001501576637100315270ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-6-node-property-indicators/000077500000000000000000000000001501576637100313775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-6-node-property-indicators/in.json000066400000000000000000000000561501576637100327010ustar00rootroot00000000000000{ "anchored": "value", "alias": "value" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-6-node-property-indicators/in.yaml000066400000000000000000000000561501576637100326720ustar00rootroot00000000000000anchored: !local &anchor value alias: *anchor goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-6-node-property-indicators/out.yaml000066400000000000000000000000561501576637100330730ustar00rootroot00000000000000anchored: &anchor !local value alias: *anchor goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-7-block-scalar-indicators/000077500000000000000000000000001501576637100311265ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-7-block-scalar-indicators/in.json000066400000000000000000000000731501576637100324270ustar00rootroot00000000000000{ "literal": "some\ntext\n", "folded": "some text\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-7-block-scalar-indicators/in.yaml000066400000000000000000000000611501576637100324150ustar00rootroot00000000000000literal: | some text folded: > some text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-7-block-scalar-indicators/out.yaml000066400000000000000000000000571501576637100326230ustar00rootroot00000000000000literal: | some text folded: > some text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-8-quoted-scalar-indicators/000077500000000000000000000000001501576637100313365ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-8-quoted-scalar-indicators/in.json000066400000000000000000000000531501576637100326350ustar00rootroot00000000000000{ "single": "text", "double": "text" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-8-quoted-scalar-indicators/in.yaml000066400000000000000000000000361501576637100326270ustar00rootroot00000000000000single: 'text' double: "text" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-9-directive-indicator/000077500000000000000000000000001501576637100303665ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-9-directive-indicator/in.json000066400000000000000000000000071501576637100316640ustar00rootroot00000000000000"text" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-9-directive-indicator/in.yaml000066400000000000000000000000231501576637100316530ustar00rootroot00000000000000%YAML 1.2 --- text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-5-9-directive-indicator/out.yaml000066400000000000000000000000111501576637100320510ustar00rootroot00000000000000--- text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-1-indentation-spaces/000077500000000000000000000000001501576637100302175ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-1-indentation-spaces/in.json000066400000000000000000000002331501576637100315160ustar00rootroot00000000000000{ "Not indented": { "By one space": "By four\n spaces\n", "Flow style": [ "By two", "Also by two", "Still by two" ] } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-1-indentation-spaces/in.yaml000066400000000000000000000004551501576637100315150ustar00rootroot00000000000000 # Leading comment line spaces are # neither content nor indentation. Not indented: By one space: | By four spaces Flow style: [ # Leading spaces By two, # in flow style Also by two, # are neither Still by two # content nor ] # indentation. goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-1-indentation-spaces/out.yaml000066400000000000000000000001631501576637100317120ustar00rootroot00000000000000Not indented: By one space: | By four spaces Flow style: - By two - Also by two - Still by two goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-10-comment-lines/000077500000000000000000000000001501576637100272615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-10-comment-lines/in.json000066400000000000000000000000001501576637100305500ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-10-comment-lines/in.yaml000066400000000000000000000000221501576637100305450ustar00rootroot00000000000000 # Comment goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-10-comment-lines/out.yaml000066400000000000000000000000001501576637100307420ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-11-multi-line-comments/000077500000000000000000000000001501576637100304125ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-11-multi-line-comments/in.json000066400000000000000000000000251501576637100317100ustar00rootroot00000000000000{ "key": "value" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-11-multi-line-comments/in.yaml000066400000000000000000000000541501576637100317030ustar00rootroot00000000000000key: # Comment # lines value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-11-multi-line-comments/out.yaml000066400000000000000000000000131501576637100320770ustar00rootroot00000000000000key: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-12-separation-spaces/000077500000000000000000000000001501576637100301325ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-12-separation-spaces/in.yaml000066400000000000000000000001411501576637100314200ustar00rootroot00000000000000{ first: Sammy, last: Sosa }: # Statistics: hr: # Home runs 65 avg: # Average 0.278 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-12-separation-spaces/out.yaml000066400000000000000000000000621501576637100316230ustar00rootroot00000000000000? first: Sammy last: Sosa : hr: 65 avg: 0.278 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-13-reserved-directives-1-3/000077500000000000000000000000001501576637100307665ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-13-reserved-directives-1-3/in.json000066400000000000000000000000061501576637100322630ustar00rootroot00000000000000"foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-13-reserved-directives-1-3/in.yaml000066400000000000000000000001141501576637100322540ustar00rootroot00000000000000%FOO bar baz # Should be ignored # with a warning. --- "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-13-reserved-directives-1-3/out.yaml000066400000000000000000000000121501576637100324520ustar00rootroot00000000000000--- "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-13-reserved-directives/000077500000000000000000000000001501576637100304705ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-13-reserved-directives/in.json000066400000000000000000000000061501576637100317650ustar00rootroot00000000000000"foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-13-reserved-directives/in.yaml000066400000000000000000000001141501576637100317560ustar00rootroot00000000000000%FOO bar baz # Should be ignored # with a warning. --- "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-13-reserved-directives/out.yaml000066400000000000000000000000121501576637100321540ustar00rootroot00000000000000--- "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-14-yaml-directive/000077500000000000000000000000001501576637100274315ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-14-yaml-directive/in.json000066400000000000000000000000061501576637100307260ustar00rootroot00000000000000"foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-14-yaml-directive/in.yaml000066400000000000000000000001011501576637100307130ustar00rootroot00000000000000%YAML 1.3 # Attempt parsing # with a warning --- "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-14-yaml-directive/out.yaml000066400000000000000000000000121501576637100311150ustar00rootroot00000000000000--- "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-16-tag-directive/000077500000000000000000000000001501576637100272445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-16-tag-directive/in.json000066400000000000000000000000061501576637100305410ustar00rootroot00000000000000"foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-16-tag-directive/in.yaml000066400000000000000000000000631501576637100305350ustar00rootroot00000000000000%TAG !yaml! tag:yaml.org,2002: --- !yaml!str "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-16-tag-directive/out.yaml000066400000000000000000000000201501576637100307270ustar00rootroot00000000000000--- !!str "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-18-primary-tag-handle-1-3/000077500000000000000000000000001501576637100305025ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-18-primary-tag-handle-1-3/in.json000066400000000000000000000000141501576637100317760ustar00rootroot00000000000000"bar" "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-18-primary-tag-handle-1-3/in.yaml000066400000000000000000000001261501576637100317730ustar00rootroot00000000000000# Private --- !foo "bar" ... # Global %TAG ! tag:example.com,2000:app/ --- !foo "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-18-primary-tag-handle-1-3/out.yaml000066400000000000000000000000751501576637100321770ustar00rootroot00000000000000--- !foo "bar" ... --- ! "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-18-primary-tag-handle/000077500000000000000000000000001501576637100302045ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-18-primary-tag-handle/in.json000066400000000000000000000000141501576637100315000ustar00rootroot00000000000000"bar" "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-18-primary-tag-handle/in.yaml000066400000000000000000000001221501576637100314710ustar00rootroot00000000000000# Private !foo "bar" ... # Global %TAG ! tag:example.com,2000:app/ --- !foo "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-18-primary-tag-handle/out.yaml000066400000000000000000000000711501576637100316750ustar00rootroot00000000000000!foo "bar" ... --- ! "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-19-secondary-tag-handle/000077500000000000000000000000001501576637100305115ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-19-secondary-tag-handle/in.json000066400000000000000000000000101501576637100320010ustar00rootroot00000000000000"1 - 3" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-19-secondary-tag-handle/in.yaml000066400000000000000000000001121501576637100317750ustar00rootroot00000000000000%TAG !! tag:example.com,2000:app/ --- !!int 1 - 3 # Interval, not integer goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-19-secondary-tag-handle/out.yaml000066400000000000000000000000521501576637100322010ustar00rootroot00000000000000--- ! 1 - 3 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-2-indentation-indicators/000077500000000000000000000000001501576637100311015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-2-indentation-indicators/in.json000066400000000000000000000000731501576637100324020ustar00rootroot00000000000000{ "a": [ "b", [ "c", "d" ] ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-2-indentation-indicators/in.yaml000066400000000000000000000000341501576637100323700ustar00rootroot00000000000000? a : - b - - c - d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-2-indentation-indicators/out.yaml000066400000000000000000000000231501576637100325670ustar00rootroot00000000000000a: - b - - c - d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-20-tag-handles/000077500000000000000000000000001501576637100266775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-20-tag-handles/in.json000066400000000000000000000000061501576637100301740ustar00rootroot00000000000000"bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-20-tag-handles/in.yaml000066400000000000000000000000641501576637100301710ustar00rootroot00000000000000%TAG !e! tag:example.com,2000:app/ --- !e!foo "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-20-tag-handles/out.yaml000066400000000000000000000000521501576637100303670ustar00rootroot00000000000000--- ! "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-21-local-tag-prefix/000077500000000000000000000000001501576637100276475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-21-local-tag-prefix/in.json000066400000000000000000000000261501576637100311460ustar00rootroot00000000000000"fluorescent" "green" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-21-local-tag-prefix/in.yaml000066400000000000000000000001451501576637100311410ustar00rootroot00000000000000%TAG !m! !my- --- # Bulb here !m!light fluorescent ... %TAG !m! !my- --- # Color here !m!light green goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-22-global-tag-prefix/000077500000000000000000000000001501576637100300165ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-22-global-tag-prefix/in.json000066400000000000000000000000141501576637100313120ustar00rootroot00000000000000[ "bar" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-22-global-tag-prefix/in.yaml000066400000000000000000000000661501576637100313120ustar00rootroot00000000000000%TAG !e! tag:example.com,2000:app/ --- - !e!foo "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-22-global-tag-prefix/out.yaml000066400000000000000000000000541501576637100315100ustar00rootroot00000000000000--- - ! "bar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-23-node-properties/000077500000000000000000000000001501576637100276325ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-23-node-properties/in.json000066400000000000000000000000431501576637100311300ustar00rootroot00000000000000{ "foo": "bar", "baz": "foo" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-23-node-properties/in.yaml000066400000000000000000000000531501576637100311220ustar00rootroot00000000000000!!str &a1 "foo": !!str bar &a2 baz : *a1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-23-node-properties/out.yaml000066400000000000000000000000501501576637100313200ustar00rootroot00000000000000&a1 !!str "foo": !!str bar &a2 baz: *a1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-24-verbatim-tags/000077500000000000000000000000001501576637100272615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-24-verbatim-tags/in.json000066400000000000000000000000231501576637100305550ustar00rootroot00000000000000{ "foo": "baz" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-24-verbatim-tags/in.yaml000066400000000000000000000000551501576637100305530ustar00rootroot00000000000000! foo : ! baz goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-24-verbatim-tags/out.yaml000066400000000000000000000000241501576637100307500ustar00rootroot00000000000000!!str foo: !bar baz goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-26-tag-shorthands/000077500000000000000000000000001501576637100274445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-26-tag-shorthands/in.json000066400000000000000000000000361501576637100307440ustar00rootroot00000000000000[ "foo", "bar", "baz" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-26-tag-shorthands/in.yaml000066400000000000000000000001201501576637100307270ustar00rootroot00000000000000%TAG !e! tag:example.com,2000:app/ --- - !local foo - !!str bar - !e!tag%21 baz goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-28-non-specific-tags/000077500000000000000000000000001501576637100300315ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-28-non-specific-tags/in.json000066400000000000000000000000311501576637100313240ustar00rootroot00000000000000[ "12", 12, "12" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-28-non-specific-tags/in.yaml000066400000000000000000000000671501576637100313260ustar00rootroot00000000000000# Assuming conventional resolution: - "12" - 12 - ! 12 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-28-non-specific-tags/out.yaml000066400000000000000000000000231501576637100315170ustar00rootroot00000000000000- "12" - 12 - ! 12 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-29-node-anchors/000077500000000000000000000000001501576637100271015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-29-node-anchors/in.json000066400000000000000000000001021501576637100303730ustar00rootroot00000000000000{ "First occurrence": "Value", "Second occurrence": "Value" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-29-node-anchors/in.yaml000066400000000000000000000000731501576637100303730ustar00rootroot00000000000000First occurrence: &anchor Value Second occurrence: *anchor goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-3-separation-spaces/000077500000000000000000000000001501576637100300525ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-3-separation-spaces/in.json000066400000000000000000000000731501576637100313530ustar00rootroot00000000000000[ { "foo": "bar" }, [ "baz", "baz" ] ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-3-separation-spaces/in.yaml000066400000000000000000000000341501576637100313410ustar00rootroot00000000000000- foo: bar - - baz - baz goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-3-separation-spaces/out.yaml000066400000000000000000000000331501576637100315410ustar00rootroot00000000000000- foo: bar - - baz - baz goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-4-line-prefixes/000077500000000000000000000000001501576637100272045ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-4-line-prefixes/in.json000066400000000000000000000001251501576637100305030ustar00rootroot00000000000000{ "plain": "text lines", "quoted": "text lines", "block": "text\n \tlines\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-4-line-prefixes/in.yaml000066400000000000000000000001061501576637100304730ustar00rootroot00000000000000plain: text lines quoted: "text lines" block: | text lines goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-4-line-prefixes/out.yaml000066400000000000000000000001011501576637100306670ustar00rootroot00000000000000plain: text lines quoted: "text lines" block: "text\n \tlines\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-5-empty-lines-1-3/000077500000000000000000000000001501576637100271775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-5-empty-lines-1-3/in.json000066400000000000000000000001251501576637100304760ustar00rootroot00000000000000{ "Folding": "Empty line\nas a line feed", "Chomping": "Clipped empty lines\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-5-empty-lines-1-3/in.yaml000066400000000000000000000001171501576637100304700ustar00rootroot00000000000000Folding: "Empty line as a line feed" Chomping: | Clipped empty lines goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-5-empty-lines-1-3/out.yaml000066400000000000000000000001101501576637100306620ustar00rootroot00000000000000Folding: "Empty line\nas a line feed" Chomping: | Clipped empty lines goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-5-empty-lines/000077500000000000000000000000001501576637100267015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-5-empty-lines/in.json000066400000000000000000000001251501576637100302000ustar00rootroot00000000000000{ "Folding": "Empty line\nas a line feed", "Chomping": "Clipped empty lines\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-5-empty-lines/in.yaml000066400000000000000000000001231501576637100301670ustar00rootroot00000000000000Folding: "Empty line as a line feed" Chomping: | Clipped empty lines goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-5-empty-lines/out.yaml000066400000000000000000000001101501576637100303640ustar00rootroot00000000000000Folding: "Empty line\nas a line feed" Chomping: | Clipped empty lines goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-6-line-folding-1-3/000077500000000000000000000000001501576637100273015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-6-line-folding-1-3/in.json000066400000000000000000000000301501576637100305730ustar00rootroot00000000000000"trimmed\n\n\nas space" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-6-line-folding-1-3/in.yaml000066400000000000000000000000441501576637100305710ustar00rootroot00000000000000--- >- trimmed as space goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-6-line-folding-1-3/out.yaml000066400000000000000000000000371501576637100307740ustar00rootroot00000000000000--- >- trimmed as space goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-6-line-folding/000077500000000000000000000000001501576637100270035ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-6-line-folding/in.json000066400000000000000000000000301501576637100302750ustar00rootroot00000000000000"trimmed\n\n\nas space" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-6-line-folding/in.yaml000066400000000000000000000000401501576637100302670ustar00rootroot00000000000000>- trimmed as space goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-6-line-folding/out.yaml000066400000000000000000000000331501576637100304720ustar00rootroot00000000000000>- trimmed as space goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-7-block-folding/000077500000000000000000000000001501576637100271475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-7-block-folding/in.json000066400000000000000000000000321501576637100304430ustar00rootroot00000000000000"foo \n\n\t bar\n\nbaz\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-7-block-folding/in.yaml000066400000000000000000000000321501576637100304340ustar00rootroot00000000000000> foo bar baz goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-7-block-folding/out.yaml000066400000000000000000000000321501576637100306350ustar00rootroot00000000000000"foo \n\n\t bar\n\nbaz\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-8-flow-folding-1-3/000077500000000000000000000000001501576637100273235ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-8-flow-folding-1-3/in.json000066400000000000000000000000221501576637100306160ustar00rootroot00000000000000" foo\nbar\nbaz " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-8-flow-folding-1-3/in.yaml000066400000000000000000000000401501576637100306070ustar00rootroot00000000000000--- " foo bar baz " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-8-flow-folding-1-3/out.yaml000066400000000000000000000000221501576637100310100ustar00rootroot00000000000000" foo\nbar\nbaz " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-8-flow-folding/000077500000000000000000000000001501576637100270255ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-8-flow-folding/in.json000066400000000000000000000000221501576637100303200ustar00rootroot00000000000000" foo\nbar\nbaz " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-8-flow-folding/in.yaml000066400000000000000000000000341501576637100303140ustar00rootroot00000000000000" foo bar baz " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-8-flow-folding/out.yaml000066400000000000000000000000221501576637100305120ustar00rootroot00000000000000" foo\nbar\nbaz " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-9-separated-comment/000077500000000000000000000000001501576637100300475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-9-separated-comment/in.json000066400000000000000000000000251501576637100313450ustar00rootroot00000000000000{ "key": "value" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-9-separated-comment/in.yaml000066400000000000000000000000321501576637100313340ustar00rootroot00000000000000key: # Comment value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-6-9-separated-comment/out.yaml000066400000000000000000000000131501576637100315340ustar00rootroot00000000000000key: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-1-alias-nodes/000077500000000000000000000000001501576637100266275ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-1-alias-nodes/in.json000066400000000000000000000001631501576637100301300ustar00rootroot00000000000000{ "First occurrence": "Foo", "Second occurrence": "Foo", "Override anchor": "Bar", "Reuse anchor": "Bar" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-1-alias-nodes/in.yaml000066400000000000000000000001541501576637100301210ustar00rootroot00000000000000First occurrence: &anchor Foo Second occurrence: *anchor Override anchor: &anchor Bar Reuse anchor: *anchor goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-10-plain-characters/000077500000000000000000000000001501576637100277305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-10-plain-characters/in.json000066400000000000000000000003061501576637100312300ustar00rootroot00000000000000[ "::vector", ": - ()", "Up, up, and away!", -123, "http://example.com/foo#bar", [ "::vector", ": - ()", "Up, up and away!", -123, "http://example.com/foo#bar" ] ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-10-plain-characters/in.yaml000066400000000000000000000003321501576637100312200ustar00rootroot00000000000000# Outside flow collection: - ::vector - ": - ()" - Up, up, and away! - -123 - http://example.com/foo#bar # Inside flow collection: - [ ::vector, ": - ()", "Up, up and away!", -123, http://example.com/foo#bar ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-10-plain-characters/out.yaml000066400000000000000000000002471501576637100314260ustar00rootroot00000000000000- ::vector - ": - ()" - Up, up, and away! - -123 - http://example.com/foo#bar - - ::vector - ": - ()" - "Up, up and away!" - -123 - http://example.com/foo#bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-11-plain-implicit-keys/000077500000000000000000000000001501576637100303755ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-11-plain-implicit-keys/in.json000066400000000000000000000001211501576637100316700ustar00rootroot00000000000000{ "implicit block key": [ { "implicit flow key": "value" } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-11-plain-implicit-keys/in.yaml000066400000000000000000000000671501576637100316720ustar00rootroot00000000000000implicit block key : [ implicit flow key : value, ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-11-plain-implicit-keys/out.yaml000066400000000000000000000000571501576637100320720ustar00rootroot00000000000000implicit block key: - implicit flow key: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-12-plain-lines/000077500000000000000000000000001501576637100267255ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-12-plain-lines/in.json000066400000000000000000000000551501576637100302260ustar00rootroot00000000000000"1st non-empty\n2nd non-empty 3rd non-empty" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-12-plain-lines/in.yaml000066400000000000000000000000561501576637100302200ustar00rootroot000000000000001st non-empty 2nd non-empty 3rd non-empty goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-12-plain-lines/out.yaml000066400000000000000000000000571501576637100304220ustar00rootroot00000000000000'1st non-empty 2nd non-empty 3rd non-empty' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-13-flow-sequence/000077500000000000000000000000001501576637100272705ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-13-flow-sequence/in.json000066400000000000000000000001021501576637100305620ustar00rootroot00000000000000[ [ "one", "two" ], [ "three", "four" ] ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-13-flow-sequence/in.yaml000066400000000000000000000000401501576637100305540ustar00rootroot00000000000000- [ one, two, ] - [three ,four] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-13-flow-sequence/out.yaml000066400000000000000000000000431501576637100307600ustar00rootroot00000000000000- - one - two - - three - four goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-14-flow-sequence-entries/000077500000000000000000000000001501576637100307405ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-14-flow-sequence-entries/in.json000066400000000000000000000001551501576637100322420ustar00rootroot00000000000000[ "double quoted", "single quoted", "plain text", [ "nested" ], { "single": "pair" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-14-flow-sequence-entries/in.yaml000066400000000000000000000001311501576637100322250ustar00rootroot00000000000000[ "double quoted", 'single quoted', plain text, [ nested ], single: pair, ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-14-flow-sequence-entries/out.yaml000066400000000000000000000001131501576637100324260ustar00rootroot00000000000000- "double quoted" - 'single quoted' - plain text - - nested - single: pair goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-15-flow-mappings/000077500000000000000000000000001501576637100273005ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-15-flow-mappings/in.json000066400000000000000000000001431501576637100305770ustar00rootroot00000000000000[ { "one": "two", "three": "four" }, { "five": "six", "seven": "eight" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-15-flow-mappings/in.yaml000066400000000000000000000000741501576637100305730ustar00rootroot00000000000000- { one : two , three: four , } - {five: six,seven : eight} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-15-flow-mappings/out.yaml000066400000000000000000000000641501576637100307730ustar00rootroot00000000000000- one: two three: four - five: six seven: eight goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-16-flow-mapping-entries/000077500000000000000000000000001501576637100305655ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-16-flow-mapping-entries/in.yaml000066400000000000000000000000521501576637100320540ustar00rootroot00000000000000{ ? explicit: entry, implicit: entry, ? } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-16-flow-mapping-entries/out.yaml000066400000000000000000000000421501576637100322540ustar00rootroot00000000000000explicit: entry implicit: entry : goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-18-flow-mapping-adjacent-values/000077500000000000000000000000001501576637100321645ustar00rootroot00000000000000in.json000066400000000000000000000001021501576637100333770ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-18-flow-mapping-adjacent-values{ "adjacent": "value", "readable": "value", "empty": null } in.yaml000066400000000000000000000000621501576637100333750ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-18-flow-mapping-adjacent-values{ "adjacent":value, "readable": value, "empty": } out.yaml000066400000000000000000000000551501576637100336000ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-18-flow-mapping-adjacent-values"adjacent": value "readable": value "empty": goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-19-single-pair-flow-mappings/000077500000000000000000000000001501576637100315145ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-19-single-pair-flow-mappings/in.json000066400000000000000000000000351501576637100330130ustar00rootroot00000000000000[ { "foo": "bar" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-19-single-pair-flow-mappings/in.yaml000066400000000000000000000000151501576637100330020ustar00rootroot00000000000000[ foo: bar ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-19-single-pair-flow-mappings/out.yaml000066400000000000000000000000131501576637100332010ustar00rootroot00000000000000- foo: bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-2-empty-content/000077500000000000000000000000001501576637100272375ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-2-empty-content/in.json000066400000000000000000000000351501576637100305360ustar00rootroot00000000000000{ "foo": "", "": "bar" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-2-empty-content/in.yaml000066400000000000000000000000421501576637100305250ustar00rootroot00000000000000{ foo : !!str, !!str : bar, } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-2-empty-content/out.yaml000066400000000000000000000000271501576637100307310ustar00rootroot00000000000000foo: !!str !!str : bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-20-single-pair-explicit-entry/000077500000000000000000000000001501576637100317015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-20-single-pair-explicit-entry/in.json000066400000000000000000000000411501576637100331750ustar00rootroot00000000000000[ { "foo bar": "baz" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-20-single-pair-explicit-entry/in.yaml000066400000000000000000000000251501576637100331700ustar00rootroot00000000000000[ ? foo bar : baz ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-20-single-pair-explicit-entry/out.yaml000066400000000000000000000000171501576637100333720ustar00rootroot00000000000000- foo bar: baz goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-23-flow-content/000077500000000000000000000000001501576637100271335ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-23-flow-content/in.json000066400000000000000000000001101501576637100304240ustar00rootroot00000000000000[ [ "a", "b" ], { "a": "b" }, "a", "b", "c" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-23-flow-content/in.yaml000066400000000000000000000000461501576637100304250ustar00rootroot00000000000000- [ a, b ] - { a: b } - "a" - 'b' - c goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-23-flow-content/out.yaml000066400000000000000000000000431501576637100306230ustar00rootroot00000000000000- - a - b - a: b - "a" - 'b' - c goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-24-flow-nodes/000077500000000000000000000000001501576637100265725ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-24-flow-nodes/in.json000066400000000000000000000000451501576637100300720ustar00rootroot00000000000000[ "a", "b", "c", "c", "" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-24-flow-nodes/in.yaml000066400000000000000000000000621501576637100300620ustar00rootroot00000000000000- !!str "a" - 'b' - &anchor "c" - *anchor - !!str goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-3-completely-empty-flow-nodes/000077500000000000000000000000001501576637100320165ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-3-completely-empty-flow-nodes/in.yaml000066400000000000000000000000301501576637100333010ustar00rootroot00000000000000{ ? foo :, : bar, } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-4-double-quoted-implicit-keys/000077500000000000000000000000001501576637100317655ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-4-double-quoted-implicit-keys/in.json000066400000000000000000000001211501576637100332600ustar00rootroot00000000000000{ "implicit block key": [ { "implicit flow key": "value" } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-4-double-quoted-implicit-keys/in.yaml000066400000000000000000000000731501576637100332570ustar00rootroot00000000000000"implicit block key" : [ "implicit flow key" : value, ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-4-double-quoted-implicit-keys/out.yaml000066400000000000000000000000631501576637100334570ustar00rootroot00000000000000"implicit block key": - "implicit flow key": value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-5-double-quoted-line-breaks-1-3/000077500000000000000000000000001501576637100316755ustar00rootroot00000000000000in.json000066400000000000000000000000721501576637100331160ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-5-double-quoted-line-breaks-1-3"folded to a space,\nto a line feed, or \t \tnon-content" in.yaml000066400000000000000000000001021501576637100331010ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-5-double-quoted-line-breaks-1-3--- "folded to a space, to a line feed, or \ \ non-content" out.yaml000066400000000000000000000000721501576637100333100ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-5-double-quoted-line-breaks-1-3"folded to a space,\nto a line feed, or \t \tnon-content" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-5-double-quoted-line-breaks/000077500000000000000000000000001501576637100313775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-5-double-quoted-line-breaks/in.json000066400000000000000000000000721501576637100326770ustar00rootroot00000000000000"folded to a space,\nto a line feed, or \t \tnon-content" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-5-double-quoted-line-breaks/in.yaml000066400000000000000000000000771501576637100326750ustar00rootroot00000000000000"folded to a space, to a line feed, or \ \ non-content" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-5-double-quoted-line-breaks/out.yaml000066400000000000000000000000721501576637100330710ustar00rootroot00000000000000"folded to a space,\nto a line feed, or \t \tnon-content" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-6-double-quoted-lines-1-3/000077500000000000000000000000001501576637100306145ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-6-double-quoted-lines-1-3/in.json000066400000000000000000000000571501576637100321170ustar00rootroot00000000000000" 1st non-empty\n2nd non-empty 3rd non-empty " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-6-double-quoted-lines-1-3/in.yaml000066400000000000000000000000661501576637100321100ustar00rootroot00000000000000--- " 1st non-empty 2nd non-empty 3rd non-empty " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-6-double-quoted-lines-1-3/out.yaml000066400000000000000000000000571501576637100323110ustar00rootroot00000000000000" 1st non-empty\n2nd non-empty 3rd non-empty " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-6-double-quoted-lines/000077500000000000000000000000001501576637100303165ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-6-double-quoted-lines/in.json000066400000000000000000000000571501576637100316210ustar00rootroot00000000000000" 1st non-empty\n2nd non-empty 3rd non-empty " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-6-double-quoted-lines/in.yaml000066400000000000000000000000621501576637100316060ustar00rootroot00000000000000" 1st non-empty 2nd non-empty 3rd non-empty " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-6-double-quoted-lines/out.yaml000066400000000000000000000000571501576637100320130ustar00rootroot00000000000000" 1st non-empty\n2nd non-empty 3rd non-empty " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-7-single-quoted-characters-1-3/000077500000000000000000000000001501576637100316315ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-7-single-quoted-characters-1-3/in.json000066400000000000000000000000271501576637100331310ustar00rootroot00000000000000"here's to \"quotes\"" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-7-single-quoted-characters-1-3/in.yaml000066400000000000000000000000321501576637100331160ustar00rootroot00000000000000--- 'here''s to "quotes"' out.yaml000066400000000000000000000000321501576637100332400ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-7-single-quoted-characters-1-3--- 'here''s to "quotes"' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-7-single-quoted-characters/000077500000000000000000000000001501576637100313335ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-7-single-quoted-characters/in.json000066400000000000000000000000271501576637100326330ustar00rootroot00000000000000"here's to \"quotes\"" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-7-single-quoted-characters/in.yaml000066400000000000000000000000261501576637100326230ustar00rootroot00000000000000'here''s to "quotes"' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-8-single-quoted-implicit-keys/000077500000000000000000000000001501576637100320005ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-8-single-quoted-implicit-keys/in.json000066400000000000000000000001211501576637100332730ustar00rootroot00000000000000{ "implicit block key": [ { "implicit flow key": "value" } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-8-single-quoted-implicit-keys/in.yaml000066400000000000000000000000731501576637100332720ustar00rootroot00000000000000'implicit block key' : [ 'implicit flow key' : value, ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-8-single-quoted-implicit-keys/out.yaml000066400000000000000000000000631501576637100334720ustar00rootroot00000000000000'implicit block key': - 'implicit flow key': value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-9-single-quoted-lines-1-3/000077500000000000000000000000001501576637100306265ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-9-single-quoted-lines-1-3/in.json000066400000000000000000000000571501576637100321310ustar00rootroot00000000000000" 1st non-empty\n2nd non-empty 3rd non-empty " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-9-single-quoted-lines-1-3/in.yaml000066400000000000000000000000661501576637100321220ustar00rootroot00000000000000--- ' 1st non-empty 2nd non-empty 3rd non-empty ' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-9-single-quoted-lines-1-3/out.yaml000066400000000000000000000000611501576637100323160ustar00rootroot00000000000000' 1st non-empty 2nd non-empty 3rd non-empty ' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-9-single-quoted-lines/000077500000000000000000000000001501576637100303305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-9-single-quoted-lines/in.json000066400000000000000000000000571501576637100316330ustar00rootroot00000000000000" 1st non-empty\n2nd non-empty 3rd non-empty " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-9-single-quoted-lines/in.yaml000066400000000000000000000000621501576637100316200ustar00rootroot00000000000000' 1st non-empty 2nd non-empty 3rd non-empty ' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-7-9-single-quoted-lines/out.yaml000066400000000000000000000000611501576637100320200ustar00rootroot00000000000000' 1st non-empty 2nd non-empty 3rd non-empty ' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-1-block-scalar-header/000077500000000000000000000000001501576637100302145ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-1-block-scalar-header/in.json000066400000000000000000000000731501576637100315150ustar00rootroot00000000000000[ "literal\n", " folded\n", "keep\n\n", " strip" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-1-block-scalar-header/in.yaml000066400000000000000000000002171501576637100315060ustar00rootroot00000000000000- | # Empty header↓ literal - >1 # Indentation indicator↓ folded - |+ # Chomping indicator↓ keep - >1- # Both indicators↓ strip goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-1-block-scalar-header/out.yaml000066400000000000000000000000711501576637100317050ustar00rootroot00000000000000- | literal - >2 folded - |+ keep - >2- strip spec-example-8-10-folded-lines-8-13-final-empty-lines/000077500000000000000000000000001501576637100327205ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suitein.json000066400000000000000000000001151501576637100342160ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-10-folded-lines-8-13-final-empty-lines"\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n" in.yaml000066400000000000000000000001301501576637100342040ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-10-folded-lines-8-13-final-empty-lines> folded line next line * bullet * list * lines last line # Comment out.yaml000066400000000000000000000001201501576637100344040ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-10-folded-lines-8-13-final-empty-lines> folded line next line * bullet * list * lines last line goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-14-block-sequence/000077500000000000000000000000001501576637100274155ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-14-block-sequence/in.json000066400000000000000000000001121501576637100307100ustar00rootroot00000000000000{ "block sequence": [ "one", { "two": "three" } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-14-block-sequence/in.yaml000066400000000000000000000000501501576637100307020ustar00rootroot00000000000000block sequence: - one - two : three goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-14-block-sequence/out.yaml000066400000000000000000000000431501576637100311050ustar00rootroot00000000000000block sequence: - one - two: three goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-15-block-sequence-entry-types/000077500000000000000000000000001501576637100317175ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-15-block-sequence-entry-types/in.json000066400000000000000000000001251501576637100332160ustar00rootroot00000000000000[ null, "block node\n", [ "one", "two" ], { "one": "two" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-15-block-sequence-entry-types/in.yaml000066400000000000000000000001341501576637100332070ustar00rootroot00000000000000- # Empty - | block node - - one # Compact - two # sequence - one: two # Compact mapping goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-15-block-sequence-entry-types/out.yaml000066400000000000000000000000561501576637100334130ustar00rootroot00000000000000- - | block node - - one - two - one: two goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-16-block-mappings/000077500000000000000000000000001501576637100274255ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-16-block-mappings/in.json000066400000000000000000000000601501576637100307220ustar00rootroot00000000000000{ "block mapping": { "key": "value" } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-16-block-mappings/in.yaml000066400000000000000000000000331501576637100307130ustar00rootroot00000000000000block mapping: key: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-16-block-mappings/out.yaml000066400000000000000000000000341501576637100311150ustar00rootroot00000000000000block mapping: key: value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-17-explicit-block-mapping-entries/000077500000000000000000000000001501576637100325315ustar00rootroot00000000000000in.json000066400000000000000000000001101501576637100337430ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-17-explicit-block-mapping-entries{ "explicit key": null, "block key\n": [ "one", "two" ] } in.yaml000066400000000000000000000001361501576637100337440ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-17-explicit-block-mapping-entries? explicit key # Empty value ? | block key : - one # Explicit compact - two # block value out.yaml000066400000000000000000000000561501576637100341460ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-17-explicit-block-mapping-entriesexplicit key: ? | block key : - one - two goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-18-implicit-block-mapping-entries/000077500000000000000000000000001501576637100325235ustar00rootroot00000000000000in.yaml000066400000000000000000000000761501576637100337410ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-18-implicit-block-mapping-entriesplain key: in-line value : # Both empty "quoted key": - entry goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-19-compact-block-mappings/000077500000000000000000000000001501576637100310545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-19-compact-block-mappings/in.yaml000066400000000000000000000000561501576637100323470ustar00rootroot00000000000000- sun: yellow - ? earth: blue : moon: white goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-2-block-indentation-indicator-1-3/000077500000000000000000000000001501576637100323065ustar00rootroot00000000000000in.json000066400000000000000000000001121501576637100335220ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-2-block-indentation-indicator-1-3[ "detected\n", "\n\n# detected\n", " explicit\n", "detected\n" ] in.yaml000066400000000000000000000001021501576637100335120ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-2-block-indentation-indicator-1-3- | detected - > # detected - |1 explicit - > detected goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-2-block-indentation-indicator/000077500000000000000000000000001501576637100320105ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-2-block-indentation-indicator/in.json000066400000000000000000000001161501576637100333070ustar00rootroot00000000000000[ "detected\n", "\n\n# detected\n", " explicit\n", "\t\ndetected\n" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-2-block-indentation-indicator/in.yaml000066400000000000000000000001051501576637100332760ustar00rootroot00000000000000- | detected - > # detected - |1 explicit - > detected goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-2-block-indentation-indicator/out.yaml000066400000000000000000000001071501576637100335010ustar00rootroot00000000000000- | detected - >2 # detected - |2 explicit - "\t\ndetected\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-20-block-node-types/000077500000000000000000000000001501576637100276715ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-20-block-node-types/in.json000066400000000000000000000001041501576637100311650ustar00rootroot00000000000000[ "flow in block", "Block scalar\n", { "foo": "bar" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-20-block-node-types/in.yaml000066400000000000000000000001151501576637100311600ustar00rootroot00000000000000- "flow in block" - > Block scalar - !!map # Block collection foo : bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-20-block-node-types/out.yaml000066400000000000000000000000701501576637100313610ustar00rootroot00000000000000- "flow in block" - > Block scalar - !!map foo: bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-21-block-scalar-nodes-1-3/000077500000000000000000000000001501576637100304545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-21-block-scalar-nodes-1-3/in.json000066400000000000000000000000621501576637100317530ustar00rootroot00000000000000{ "literal": "value\n", "folded": "value\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-21-block-scalar-nodes-1-3/in.yaml000066400000000000000000000000531501576637100317440ustar00rootroot00000000000000literal: |2 value folded: !foo >1 value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-21-block-scalar-nodes-1-3/out.yaml000066400000000000000000000000521501576637100321440ustar00rootroot00000000000000literal: | value folded: !foo > value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-21-block-scalar-nodes/000077500000000000000000000000001501576637100301565ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-21-block-scalar-nodes/in.json000066400000000000000000000000621501576637100314550ustar00rootroot00000000000000{ "literal": "value\n", "folded": "value\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-21-block-scalar-nodes/in.yaml000066400000000000000000000000601501576637100314440ustar00rootroot00000000000000literal: |2 value folded: !foo >1 value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-21-block-scalar-nodes/out.yaml000066400000000000000000000000521501576637100316460ustar00rootroot00000000000000literal: | value folded: !foo > value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-22-block-collection-nodes/000077500000000000000000000000001501576637100310455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-22-block-collection-nodes/in.json000066400000000000000000000001451501576637100323460ustar00rootroot00000000000000{ "sequence": [ "entry", [ "nested" ] ], "mapping": { "foo": "bar" } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-22-block-collection-nodes/in.yaml000066400000000000000000000001031501576637100323310ustar00rootroot00000000000000sequence: !!seq - entry - !!seq - nested mapping: !!map foo: bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-22-block-collection-nodes/out.yaml000066400000000000000000000001051501576637100325340ustar00rootroot00000000000000sequence: !!seq - entry - !!seq - nested mapping: !!map foo: bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-4-chomping-final-line-break/000077500000000000000000000000001501576637100313365ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-4-chomping-final-line-break/in.json000066400000000000000000000000761501576637100326420ustar00rootroot00000000000000{ "strip": "text", "clip": "text\n", "keep": "text\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-4-chomping-final-line-break/in.yaml000066400000000000000000000000601501576637100326240ustar00rootroot00000000000000strip: |- text clip: | text keep: |+ text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-4-chomping-final-line-break/out.yaml000066400000000000000000000000571501576637100330330ustar00rootroot00000000000000strip: |- text clip: | text keep: | text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-5-chomping-trailing-lines/000077500000000000000000000000001501576637100311605ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-5-chomping-trailing-lines/in.json000066400000000000000000000001061501576637100324560ustar00rootroot00000000000000{ "strip": "# text", "clip": "# text\n", "keep": "# text\n\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-5-chomping-trailing-lines/in.yaml000066400000000000000000000002301501576637100324450ustar00rootroot00000000000000 # Strip # Comments: strip: |- # text # Clip # comments: clip: | # text # Keep # comments: keep: |+ # text # Trail # comments. goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-5-chomping-trailing-lines/out.yaml000066400000000000000000000000731501576637100326530ustar00rootroot00000000000000strip: |- # text clip: | # text keep: |+ # text ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-6-empty-scalar-chomping/000077500000000000000000000000001501576637100306415ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-6-empty-scalar-chomping/in.json000066400000000000000000000000601501576637100321360ustar00rootroot00000000000000{ "strip": "", "clip": "", "keep": "\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-6-empty-scalar-chomping/in.yaml000066400000000000000000000000361501576637100321320ustar00rootroot00000000000000strip: >- clip: > keep: |+ goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-6-empty-scalar-chomping/out.yaml000066400000000000000000000000421501576637100323300ustar00rootroot00000000000000strip: "" clip: "" keep: |2+ ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-7-literal-scalar-1-3/000077500000000000000000000000001501576637100276345ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-7-literal-scalar-1-3/in.json000066400000000000000000000000241501576637100311310ustar00rootroot00000000000000"literal\n\ttext\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-7-literal-scalar-1-3/in.yaml000066400000000000000000000000301501576637100311170ustar00rootroot00000000000000--- | literal text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-7-literal-scalar-1-3/out.yaml000066400000000000000000000000241501576637100313230ustar00rootroot00000000000000"literal\n\ttext\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-7-literal-scalar/000077500000000000000000000000001501576637100273365ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-7-literal-scalar/in.json000066400000000000000000000000241501576637100306330ustar00rootroot00000000000000"literal\n\ttext\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-7-literal-scalar/in.yaml000066400000000000000000000000241501576637100306240ustar00rootroot00000000000000| literal text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-7-literal-scalar/out.yaml000066400000000000000000000000241501576637100310250ustar00rootroot00000000000000| literal text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-8-literal-content-1-3/000077500000000000000000000000001501576637100300425ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-8-literal-content-1-3/in.json000066400000000000000000000000331501576637100313370ustar00rootroot00000000000000"\n\nliteral\n \n\ntext\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-8-literal-content-1-3/in.yaml000066400000000000000000000000571501576637100313360ustar00rootroot00000000000000--- | literal text # Comment goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-8-literal-content-1-3/out.yaml000066400000000000000000000000331501576637100315310ustar00rootroot00000000000000"\n\nliteral\n \n\ntext\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-8-literal-content/000077500000000000000000000000001501576637100275445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-8-literal-content/in.json000066400000000000000000000000331501576637100310410ustar00rootroot00000000000000"\n\nliteral\n \n\ntext\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-8-literal-content/in.yaml000066400000000000000000000000531501576637100310340ustar00rootroot00000000000000| literal text # Comment goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-8-literal-content/out.yaml000066400000000000000000000000331501576637100312330ustar00rootroot00000000000000"\n\nliteral\n \n\ntext\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-9-folded-scalar-1-3/000077500000000000000000000000001501576637100274375ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-9-folded-scalar-1-3/in.json000066400000000000000000000000201501576637100307300ustar00rootroot00000000000000"folded text\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-9-folded-scalar-1-3/in.yaml000066400000000000000000000000261501576637100307270ustar00rootroot00000000000000--- > folded text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-9-folded-scalar-1-3/out.yaml000066400000000000000000000000201501576637100311220ustar00rootroot00000000000000> folded text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-9-folded-scalar/000077500000000000000000000000001501576637100271415ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-9-folded-scalar/in.json000066400000000000000000000000201501576637100304320ustar00rootroot00000000000000"folded text\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-9-folded-scalar/in.yaml000066400000000000000000000000221501576637100304250ustar00rootroot00000000000000> folded text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-8-9-folded-scalar/out.yaml000066400000000000000000000000201501576637100306240ustar00rootroot00000000000000> folded text goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-2-document-markers/000077500000000000000000000000001501576637100277135ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-2-document-markers/in.json000066400000000000000000000000131501576637100312060ustar00rootroot00000000000000"Document" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-2-document-markers/in.yaml000066400000000000000000000000441501576637100312030ustar00rootroot00000000000000%YAML 1.2 --- Document ... # Suffix goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-2-document-markers/out.yaml000066400000000000000000000000211501576637100313770ustar00rootroot00000000000000--- Document ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-3-bare-documents/000077500000000000000000000000001501576637100273445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-3-bare-documents/in.json000066400000000000000000000000701501576637100306420ustar00rootroot00000000000000"Bare document" "%!PS-Adobe-2.0 # Not the first line\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-3-bare-documents/in.yaml000066400000000000000000000001121501576637100306300ustar00rootroot00000000000000Bare document ... # No document ... | %!PS-Adobe-2.0 # Not the first line goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-4-explicit-documents/000077500000000000000000000000001501576637100302555ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-4-explicit-documents/in.json000066400000000000000000000000331501576637100315520ustar00rootroot00000000000000{ "matches %": 20 } null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-4-explicit-documents/in.yaml000066400000000000000000000000531501576637100315450ustar00rootroot00000000000000--- { matches % : 20 } ... --- # Empty ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-4-explicit-documents/out.yaml000066400000000000000000000000361501576637100317470ustar00rootroot00000000000000--- matches %: 20 ... --- ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-5-directives-documents/000077500000000000000000000000001501576637100305765ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-5-directives-documents/in.json000066400000000000000000000000301501576637100320700ustar00rootroot00000000000000"%!PS-Adobe-2.0\n" null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-5-directives-documents/in.yaml000066400000000000000000000000751501576637100320720ustar00rootroot00000000000000%YAML 1.2 --- | %!PS-Adobe-2.0 ... %YAML 1.2 --- # Empty ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-5-directives-documents/out.yaml000066400000000000000000000000431501576637100322660ustar00rootroot00000000000000--- | %!PS-Adobe-2.0 ... --- ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-6-stream-1-3/000077500000000000000000000000001501576637100262305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-6-stream-1-3/in.json000066400000000000000000000000671501576637100275340ustar00rootroot00000000000000{ "Mapping": "Document" } null { "matches %": 20 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-6-stream-1-3/in.yaml000066400000000000000000000000761501576637100275250ustar00rootroot00000000000000Mapping: Document --- # Empty ... %YAML 1.2 --- matches %: 20 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-6-stream/000077500000000000000000000000001501576637100257325ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-6-stream/in.json000066400000000000000000000000461501576637100272330ustar00rootroot00000000000000"Document" null { "matches %": 20 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/spec-example-9-6-stream/in.yaml000066400000000000000000000000651501576637100272250ustar00rootroot00000000000000Document --- # Empty ... %YAML 1.2 --- matches %: 20 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/syntax-character-edge-cases/000077500000000000000000000000001501576637100270235ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/syntax-character-edge-cases/00/000077500000000000000000000000001501576637100272425ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/syntax-character-edge-cases/00/in.yaml000066400000000000000000000000041501576637100305260ustar00rootroot00000000000000- : goccy-go-yaml-52dacb8/testdata/yaml-test-suite/syntax-character-edge-cases/01/000077500000000000000000000000001501576637100272435ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/syntax-character-edge-cases/01/in.json000066400000000000000000000000201501576637100305340ustar00rootroot00000000000000{ ":": null } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/syntax-character-edge-cases/01/in.yaml000066400000000000000000000000031501576637100305260ustar00rootroot00000000000000:: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/syntax-character-edge-cases/02/000077500000000000000000000000001501576637100272445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/syntax-character-edge-cases/02/in.yaml000066400000000000000000000000021501576637100305260ustar00rootroot00000000000000! goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-after-document-header/000077500000000000000000000000001501576637100264545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-after-document-header/in.json000066400000000000000000000000111501576637100277450ustar00rootroot00000000000000"scalar" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-after-document-header/in.yaml000066400000000000000000000000131501576637100277400ustar00rootroot00000000000000--- scalar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-after-document-header/out.yaml000066400000000000000000000000171501576637100301450ustar00rootroot00000000000000--- scalar ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-at-beginning-of-line-followed-by-a-flow-mapping/000077500000000000000000000000001501576637100332375ustar00rootroot00000000000000in.json000066400000000000000000000000031501576637100344520ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-at-beginning-of-line-followed-by-a-flow-mapping{} in.yaml000066400000000000000000000000041501576637100344440ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-at-beginning-of-line-followed-by-a-flow-mapping {} out.yaml000066400000000000000000000000031501576637100346440ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-at-beginning-of-line-followed-by-a-flow-mapping{} goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-indented-top-flow/000077500000000000000000000000001501576637100256505ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-indented-top-flow/in.json000066400000000000000000000000031501576637100271420ustar00rootroot00000000000000[] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tab-indented-top-flow/in.yaml000066400000000000000000000000061501576637100271360ustar00rootroot00000000000000 [ ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/000077500000000000000000000000001501576637100264355ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/000/000077500000000000000000000000001501576637100267345ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/000/error000066400000000000000000000000001501576637100277760ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/000/in.yaml000066400000000000000000000000201501576637100302160ustar00rootroot00000000000000foo: | bar: 1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/001/000077500000000000000000000000001501576637100267355ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/001/in.json000066400000000000000000000000401501576637100302300ustar00rootroot00000000000000{ "foo": "\t\n", "bar": 1 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/001/in.yaml000066400000000000000000000000211501576637100302200ustar00rootroot00000000000000foo: | bar: 1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/001/out.yaml000066400000000000000000000000221501576637100304220ustar00rootroot00000000000000foo: | bar: 1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/002/000077500000000000000000000000001501576637100267365ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/002/in.json000066400000000000000000000000261501576637100302350ustar00rootroot00000000000000[ [ "foo" ] ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/002/in.yaml000066400000000000000000000000161501576637100302250ustar00rootroot00000000000000- [ foo ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/002/out.yaml000066400000000000000000000000101501576637100304200ustar00rootroot00000000000000- - foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/003/000077500000000000000000000000001501576637100267375ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/003/error000066400000000000000000000000001501576637100300010ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/003/in.yaml000066400000000000000000000000221501576637100302230ustar00rootroot00000000000000- [ foo, foo ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/003/out.yaml000066400000000000000000000000101501576637100304210ustar00rootroot00000000000000- - foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/004/000077500000000000000000000000001501576637100267405ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/004/error000066400000000000000000000000001501576637100300020ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/004/in.yaml000066400000000000000000000000041501576637100302240ustar00rootroot00000000000000- - goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/004/out.yaml000066400000000000000000000000101501576637100304220ustar00rootroot00000000000000- - foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/005/000077500000000000000000000000001501576637100267415ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/005/error000066400000000000000000000000001501576637100300030ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/005/in.yaml000066400000000000000000000000051501576637100302260ustar00rootroot00000000000000- - goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/005/out.yaml000066400000000000000000000000101501576637100304230ustar00rootroot00000000000000- - foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/006/000077500000000000000000000000001501576637100267425ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/006/error000066400000000000000000000000001501576637100300040ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/006/in.yaml000066400000000000000000000000041501576637100302260ustar00rootroot00000000000000? - goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/006/out.yaml000066400000000000000000000000101501576637100304240ustar00rootroot00000000000000- - foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/007/000077500000000000000000000000001501576637100267435ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/007/error000066400000000000000000000000001501576637100300050ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/007/in.yaml000066400000000000000000000000101501576637100302240ustar00rootroot00000000000000? - : - goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/007/out.yaml000066400000000000000000000000101501576637100304250ustar00rootroot00000000000000- - foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/008/000077500000000000000000000000001501576637100267445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/008/error000066400000000000000000000000001501576637100300060ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/008/in.yaml000066400000000000000000000000071501576637100302330ustar00rootroot00000000000000? key: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/008/out.yaml000066400000000000000000000000101501576637100304260ustar00rootroot00000000000000- - foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/009/000077500000000000000000000000001501576637100267455ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/009/error000066400000000000000000000000001501576637100300070ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/009/in.yaml000066400000000000000000000000161501576637100302340ustar00rootroot00000000000000? key: : key: goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/009/out.yaml000066400000000000000000000000101501576637100304270ustar00rootroot00000000000000- - foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/010/000077500000000000000000000000001501576637100267355ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/010/in.json000066400000000000000000000000111501576637100302260ustar00rootroot00000000000000[ -1 ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/010/in.yaml000066400000000000000000000000051501576637100302220ustar00rootroot00000000000000- -1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-in-various-contexts/010/out.yaml000066400000000000000000000000051501576637100304230ustar00rootroot00000000000000- -1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/000077500000000000000000000000001501576637100276325ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/00/000077500000000000000000000000001501576637100300515ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/00/in.json000066400000000000000000000000241501576637100313460ustar00rootroot00000000000000{ "foo" : "bar" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/00/in.yaml000066400000000000000000000000131501576637100313350ustar00rootroot00000000000000foo: bar goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/01/000077500000000000000000000000001501576637100300525ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/01/error000066400000000000000000000000001501576637100311140ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/01/in.json000066400000000000000000000000241501576637100313470ustar00rootroot00000000000000{ "foo" : "bar" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/01/in.yaml000066400000000000000000000000201501576637100313340ustar00rootroot00000000000000foo: "bar baz" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/02/000077500000000000000000000000001501576637100300535ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/02/in.json000066400000000000000000000000301501576637100313450ustar00rootroot00000000000000{ "foo" : "bar baz" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/02/in.yaml000066400000000000000000000000221501576637100313370ustar00rootroot00000000000000foo: "bar baz" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/03/000077500000000000000000000000001501576637100300545ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/03/in.json000066400000000000000000000000201501576637100313450ustar00rootroot00000000000000{ "foo" : 1 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/03/in.yaml000066400000000000000000000000121501576637100313370ustar00rootroot00000000000000 foo: 1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/04/000077500000000000000000000000001501576637100300555ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/04/in.json000066400000000000000000000000351501576637100313540ustar00rootroot00000000000000{ "foo" : 1, "bar" : 2 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/04/in.yaml000066400000000000000000000000201501576637100313370ustar00rootroot00000000000000foo: 1 bar: 2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/05/000077500000000000000000000000001501576637100300565ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/05/in.json000066400000000000000000000000351501576637100313550ustar00rootroot00000000000000{ "foo" : 1, "bar" : 2 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/05/in.yaml000066400000000000000000000000211501576637100313410ustar00rootroot00000000000000foo: 1 bar: 2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/06/000077500000000000000000000000001501576637100300575ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/06/error000066400000000000000000000000001501576637100311210ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/06/in.json000066400000000000000000000000351501576637100313560ustar00rootroot00000000000000{ "foo" : 1, "bar" : 2 } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/06/in.yaml000066400000000000000000000000241501576637100313450ustar00rootroot00000000000000foo: a: 1 b: 2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/07/000077500000000000000000000000001501576637100300605ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/07/in.json000066400000000000000000000000051501576637100313540ustar00rootroot00000000000000null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/07/in.yaml000066400000000000000000000000201501576637100313420ustar00rootroot00000000000000%YAML 1.2 --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/08/000077500000000000000000000000001501576637100300615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/08/in.json000066400000000000000000000000371501576637100313620ustar00rootroot00000000000000{ "foo" : "bar baz \t \t " } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tabs-that-look-like-indentation/08/in.yaml000066400000000000000000000000311501576637100313450ustar00rootroot00000000000000foo: "bar baz " tag-shorthand-used-in-documents-but-only-defined-in-the-first/000077500000000000000000000000001501576637100352445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suiteerror000066400000000000000000000000001501576637100363060ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tag-shorthand-used-in-documents-but-only-defined-in-the-firstin.yaml000066400000000000000000000001351501576637100365350ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tag-shorthand-used-in-documents-but-only-defined-in-the-first%TAG !prefix! tag:example.com,2011: --- !prefix!A a: b --- !prefix!B c: d --- !prefix!C e: f goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-block-objects/000077500000000000000000000000001501576637100260065ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-block-objects/in.json000066400000000000000000000000751501576637100273110ustar00rootroot00000000000000{ "foo": [ "a", { "key": "value" } ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-block-objects/in.yaml000066400000000000000000000000661501576637100273020ustar00rootroot00000000000000foo: !!seq - !!str a - !!map key: !!str value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-block-objects/out.yaml000066400000000000000000000000601501576637100274750ustar00rootroot00000000000000foo: !!seq - !!str a - !!map key: !!str value goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-flow-objects/000077500000000000000000000000001501576637100256635ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-flow-objects/in.json000066400000000000000000000000421501576637100271600ustar00rootroot00000000000000{ "k": [ "a", "b" ] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-flow-objects/in.yaml000066400000000000000000000000451501576637100271540ustar00rootroot00000000000000!!map { k: !!seq [ a, !!str b] } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-flow-objects/out.yaml000066400000000000000000000000351501576637100273540ustar00rootroot00000000000000!!map k: !!seq - a - !!str b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-root-objects/000077500000000000000000000000001501576637100256775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-root-objects/in.json000066400000000000000000000000371501576637100272000ustar00rootroot00000000000000{ "a": "b" } [ "c" ] "d e" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-root-objects/in.yaml000066400000000000000000000000641501576637100271710ustar00rootroot00000000000000--- !!map ? a : b --- !!seq - !!str c --- !!str d e goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-for-root-objects/out.yaml000066400000000000000000000000611501576637100273670ustar00rootroot00000000000000--- !!map a: b --- !!seq - !!str c --- !!str d e goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-block-sequence/000077500000000000000000000000001501576637100260055ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-block-sequence/in.json000066400000000000000000000000361501576637100273050ustar00rootroot00000000000000[ "a", "b", 42, "d" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-block-sequence/in.yaml000066400000000000000000000000411501576637100272720ustar00rootroot00000000000000 - !!str a - b - !!int 42 - d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-block-sequence/out.yaml000066400000000000000000000000351501576637100274760ustar00rootroot00000000000000- !!str a - b - !!int 42 - d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-explicit-mapping/000077500000000000000000000000001501576637100263575ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-explicit-mapping/in.json000066400000000000000000000000321501576637100276530ustar00rootroot00000000000000{ "a": 47, "c": "d" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-explicit-mapping/in.yaml000066400000000000000000000000431501576637100276460ustar00rootroot00000000000000? !!str a : !!int 47 ? c : !!str d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-explicit-mapping/out.yaml000066400000000000000000000000351501576637100300500ustar00rootroot00000000000000!!str a: !!int 47 c: !!str d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-implicit-mapping/000077500000000000000000000000001501576637100263505ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-implicit-mapping/in.json000066400000000000000000000001011501576637100276410ustar00rootroot00000000000000{ "a": "b", "c": 42, "e": "f", "g": "h", "23": false } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-implicit-mapping/in.yaml000066400000000000000000000000761501576637100276450ustar00rootroot00000000000000!!str a: b c: !!int 42 e: !!str f g: h !!str 23: !!bool false goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-in-implicit-mapping/out.yaml000066400000000000000000000000761501576637100300460ustar00rootroot00000000000000!!str a: b c: !!int 42 e: !!str f g: h !!str 23: !!bool false goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-on-empty-scalars/000077500000000000000000000000001501576637100256775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-on-empty-scalars/in.yaml000066400000000000000000000000631501576637100271700ustar00rootroot00000000000000- !!str - !!null : a b: !!str - !!str : !!null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/tags-on-empty-scalars/out.yaml000066400000000000000000000000611501576637100273670ustar00rootroot00000000000000- !!str - !!null : a b: !!str - !!str : !!null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-dashes-and-content-without-space-1-3/000077500000000000000000000000001501576637100314215ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-dashes-and-content-without-space-1-3/in.json000066400000000000000000000000211501576637100327130ustar00rootroot00000000000000"---word1 word2" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-dashes-and-content-without-space-1-3/in.yaml000066400000000000000000000000231501576637100327060ustar00rootroot00000000000000--- ---word1 word2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-dashes-and-content-without-space-1-3/out.yaml000066400000000000000000000000211501576637100331050ustar00rootroot00000000000000'---word1 word2' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-dashes-and-content-without-space/000077500000000000000000000000001501576637100311235ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-dashes-and-content-without-space/in.json000066400000000000000000000000211501576637100324150ustar00rootroot00000000000000"---word1 word2" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-dashes-and-content-without-space/in.yaml000066400000000000000000000000171501576637100324130ustar00rootroot00000000000000---word1 word2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-dashes-and-content-without-space/out.yaml000066400000000000000000000000211501576637100326070ustar00rootroot00000000000000'---word1 word2' goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-explicit-integers-in-a-block-sequence/000077500000000000000000000000001501576637100320315ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-explicit-integers-in-a-block-sequence/in.json000066400000000000000000000000241501576637100333260ustar00rootroot00000000000000[ 1, -2, 33 ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-explicit-integers-in-a-block-sequence/in.yaml000066400000000000000000000000441501576637100333210ustar00rootroot00000000000000--- - !!int 1 - !!int -2 - !!int 33 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/three-explicit-integers-in-a-block-sequence/out.yaml000066400000000000000000000000441501576637100335220ustar00rootroot00000000000000--- - !!int 1 - !!int -2 - !!int 33 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-comment-in-multiline-plain-scalar/000077500000000000000000000000001501576637100317665ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-comment-in-multiline-plain-scalar/error000066400000000000000000000000001501576637100330300ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-comment-in-multiline-plain-scalar/in.yaml000066400000000000000000000000571501576637100332620ustar00rootroot00000000000000--- plain: a b # end of scalar c goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-content-after-quoted-value/000077500000000000000000000000001501576637100305365ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-content-after-quoted-value/error000066400000000000000000000000001501576637100316000ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-content-after-quoted-value/in.yaml000066400000000000000000000001011501576637100320200ustar00rootroot00000000000000key1: "quoted1" key2: "quoted2" trailing content key3: "quoted3" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-content-that-looks-like-a-mapping/000077500000000000000000000000001501576637100317025ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-content-that-looks-like-a-mapping/error000066400000000000000000000000001501576637100327440ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-content-that-looks-like-a-mapping/in.yaml000066400000000000000000000001021501576637100331650ustar00rootroot00000000000000key1: "quoted1" key2: "quoted2" no key: nor value key3: "quoted3" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-line-of-spaces/000077500000000000000000000000001501576637100261615ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-line-of-spaces/00/000077500000000000000000000000001501576637100264005ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-line-of-spaces/00/in.json000066400000000000000000000000271501576637100277000ustar00rootroot00000000000000{ "foo" : "x\n \n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-line-of-spaces/00/in.yaml000066400000000000000000000000171501576637100276700ustar00rootroot00000000000000foo: | x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-line-of-spaces/01/000077500000000000000000000000001501576637100264015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-line-of-spaces/01/in.json000066400000000000000000000000271501576637100277010ustar00rootroot00000000000000{ "foo" : "x\n \n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-line-of-spaces/01/in.yaml000066400000000000000000000000161501576637100276700ustar00rootroot00000000000000foo: | x goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-spaces-after-flow-collection/000077500000000000000000000000001501576637100310275ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-spaces-after-flow-collection/in.json000066400000000000000000000000221501576637100323220ustar00rootroot00000000000000[ 1, 2, 3 ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-spaces-after-flow-collection/in.yaml000066400000000000000000000000201501576637100323110ustar00rootroot00000000000000 [1, 2, 3] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-spaces-after-flow-collection/out.yaml000066400000000000000000000000141501576637100325150ustar00rootroot00000000000000- 1 - 2 - 3 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/000077500000000000000000000000001501576637100274605ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/00/000077500000000000000000000000001501576637100276775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/00/in.json000066400000000000000000000000231501576637100311730ustar00rootroot00000000000000"1 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/00/in.yaml000066400000000000000000000000271501576637100311700ustar00rootroot00000000000000"1 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/00/out.yaml000066400000000000000000000000231501576637100313650ustar00rootroot00000000000000"1 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/01/000077500000000000000000000000001501576637100277005ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/01/in.json000066400000000000000000000000231501576637100311740ustar00rootroot00000000000000"2 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/01/in.yaml000066400000000000000000000000311501576637100311640ustar00rootroot00000000000000"2 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/01/out.yaml000066400000000000000000000000231501576637100313660ustar00rootroot00000000000000"2 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/02/000077500000000000000000000000001501576637100277015ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/02/in.json000066400000000000000000000000231501576637100311750ustar00rootroot00000000000000"3 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/02/in.yaml000066400000000000000000000000271501576637100311720ustar00rootroot00000000000000"3 trailing\ tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/02/out.yaml000066400000000000000000000000231501576637100313670ustar00rootroot00000000000000"3 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/03/000077500000000000000000000000001501576637100277025ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/03/in.json000066400000000000000000000000231501576637100311760ustar00rootroot00000000000000"4 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/03/in.yaml000066400000000000000000000000311501576637100311660ustar00rootroot00000000000000"4 trailing\ tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/03/out.yaml000066400000000000000000000000231501576637100313700ustar00rootroot00000000000000"4 trailing\t tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/04/000077500000000000000000000000001501576637100277035ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/04/in.json000066400000000000000000000000211501576637100311750ustar00rootroot00000000000000"5 trailing tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/04/in.yaml000066400000000000000000000000261501576637100311730ustar00rootroot00000000000000"5 trailing tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/04/out.yaml000066400000000000000000000000211501576637100313670ustar00rootroot00000000000000"5 trailing tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/05/000077500000000000000000000000001501576637100277045ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/05/in.json000066400000000000000000000000211501576637100311760ustar00rootroot00000000000000"6 trailing tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/05/in.yaml000066400000000000000000000000301501576637100311670ustar00rootroot00000000000000"6 trailing tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-tabs-in-double-quoted/05/out.yaml000066400000000000000000000000211501576637100313700ustar00rootroot00000000000000"6 trailing tab" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/000077500000000000000000000000001501576637100275705ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/00/000077500000000000000000000000001501576637100300075ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/00/in.json000066400000000000000000000000151501576637100313040ustar00rootroot00000000000000[ "\n\n" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/00/in.yaml000066400000000000000000000000071501576637100312760ustar00rootroot00000000000000- |+ goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/00/out.yaml000066400000000000000000000000131501576637100314740ustar00rootroot00000000000000- |+ ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/01/000077500000000000000000000000001501576637100300105ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/01/in.json000066400000000000000000000000131501576637100313030ustar00rootroot00000000000000[ "\n" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/01/in.yaml000066400000000000000000000000111501576637100312720ustar00rootroot00000000000000- |+ goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/01/out.yaml000066400000000000000000000000121501576637100314740ustar00rootroot00000000000000- |+ ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/02/000077500000000000000000000000001501576637100300115ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/02/in.json000066400000000000000000000000131501576637100313040ustar00rootroot00000000000000[ "\n" ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/02/in.yaml000066400000000000000000000000101501576637100312720ustar00rootroot00000000000000- |+ goccy-go-yaml-52dacb8/testdata/yaml-test-suite/trailing-whitespace-in-streams/02/out.yaml000066400000000000000000000000121501576637100314750ustar00rootroot00000000000000- |+ ... goccy-go-yaml-52dacb8/testdata/yaml-test-suite/two-document-start-markers/000077500000000000000000000000001501576637100267675ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/two-document-start-markers/in.json000066400000000000000000000000121501576637100302610ustar00rootroot00000000000000null null goccy-go-yaml-52dacb8/testdata/yaml-test-suite/two-document-start-markers/in.yaml000066400000000000000000000000101501576637100302500ustar00rootroot00000000000000--- --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/two-document-start-markers/out.yaml000066400000000000000000000000101501576637100304510ustar00rootroot00000000000000--- --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/two-scalar-docs-with-trailing-comments/000077500000000000000000000000001501576637100311525ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/two-scalar-docs-with-trailing-comments/in.json000066400000000000000000000000141501576637100324460ustar00rootroot00000000000000"foo" "foo" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/two-scalar-docs-with-trailing-comments/in.yaml000066400000000000000000000000461501576637100324440ustar00rootroot00000000000000--- foo # comment --- foo # comment goccy-go-yaml-52dacb8/testdata/yaml-test-suite/two-scalar-docs-with-trailing-comments/out.yaml000066400000000000000000000000201501576637100326350ustar00rootroot00000000000000--- foo --- foo goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-combinations-of-explicit-block-mappings/000077500000000000000000000000001501576637100330455ustar00rootroot00000000000000in.yaml000066400000000000000000000001741501576637100342620ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-combinations-of-explicit-block-mappingscomplex1: ? - a complex2: ? - a : b complex3: ? - a : > b complex4: ? > a : complex5: ? - a : - b out.yaml000066400000000000000000000002001501576637100344510ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-combinations-of-explicit-block-mappingscomplex1: ? - a : complex2: ? - a : b complex3: ? - a : > b complex4: ? > a : complex5: ? - a : - b goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-combinations-of-tags-and-anchors/000077500000000000000000000000001501576637100314515ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-combinations-of-tags-and-anchors/in.json000066400000000000000000000002071501576637100327510ustar00rootroot00000000000000"scalar1" "scalar2" "scalar3" { "key5": "value4" } { "a6": 1, "b6": 2 } { "key8": "value7" } { "key10": "value9" } "value11" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-combinations-of-tags-and-anchors/in.yaml000066400000000000000000000003331501576637100327420ustar00rootroot00000000000000--- &a1 !!str scalar1 --- !!str &a2 scalar2 --- &a3 !!str scalar3 --- &a4 !!map &a5 !!str key5: value4 --- a6: 1 &anchor6 b6: 2 --- !!map &a8 !!str key8: value7 --- !!map !!str &a10 key10: value9 --- !!str &a11 value11 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-combinations-of-tags-and-anchors/out.yaml000066400000000000000000000003331501576637100331430ustar00rootroot00000000000000--- &a1 !!str scalar1 --- &a2 !!str scalar2 --- &a3 !!str scalar3 --- &a4 !!map &a5 !!str key5: value4 --- a6: 1 &anchor6 b6: 2 --- !!map &a8 !!str key8: value7 --- !!map &a10 !!str key10: value9 --- &a11 !!str value11 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-empty-or-newline-only-quoted-strings/000077500000000000000000000000001501576637100324135ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-empty-or-newline-only-quoted-strings/in.json000066400000000000000000000001531501576637100337130ustar00rootroot00000000000000{ "a": " ", "b": " ", "c": " ", "d": " ", "e": "\n", "f": "\n", "g": "\n\n", "h": "\n\n" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-empty-or-newline-only-quoted-strings/in.yaml000066400000000000000000000001261501576637100337040ustar00rootroot00000000000000--- a: ' ' b: ' ' c: " " d: " " e: ' ' f: " " g: ' ' h: " " goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-location-of-anchors-in-flow-sequence/000077500000000000000000000000001501576637100322575ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-location-of-anchors-in-flow-sequence/in.json000066400000000000000000000001331501576637100335550ustar00rootroot00000000000000[ { "a": "b" }, { "c": "d" }, { "e": "f" }, { "g": "h" } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-location-of-anchors-in-flow-sequence/in.yaml000066400000000000000000000000711501576637100335470ustar00rootroot00000000000000&flowseq [ a: b, &c c: d, { &e e: f }, &g { g: h } ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-location-of-anchors-in-flow-sequence/out.yaml000066400000000000000000000000601501576637100337460ustar00rootroot00000000000000&flowseq - a: b - &c c: d - &e e: f - &g g: h goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-comments-1-3/000077500000000000000000000000001501576637100271655ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-comments-1-3/in.yaml000066400000000000000000000002351501576637100304570ustar00rootroot00000000000000a: "double quotes" # lala b: plain value # lala c : #lala d ? # lala - seq1 : # lala - #lala seq2 e: &node # lala - x: y block: > # lala abcde goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-comments-1-3/out.yaml000066400000000000000000000001321501576637100306540ustar00rootroot00000000000000a: "double quotes" b: plain value c: d ? - seq1 : - seq2 e: &node - x: y block: > abcde goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-comments/000077500000000000000000000000001501576637100266675ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-comments/in.yaml000066400000000000000000000002361501576637100301620ustar00rootroot00000000000000a: "double quotes" # lala b: plain value # lala c : #lala d ? # lala - seq1 : # lala - #lala seq2 e: &node # lala - x: y block: > # lala abcde goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-comments/out.yaml000066400000000000000000000001321501576637100303560ustar00rootroot00000000000000a: "double quotes" b: plain value c: d ? - seq1 : - seq2 e: &node - x: y block: > abcde goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-tabs/000077500000000000000000000000001501576637100257735ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-tabs/in.json000066400000000000000000000000631501576637100272730ustar00rootroot00000000000000{ "a": "b", "seq": [ "a" ], "c": "d" } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-tabs/in.yaml000066400000000000000000000000321501576637100272600ustar00rootroot00000000000000a: b seq: - a c: d #X goccy-go-yaml-52dacb8/testdata/yaml-test-suite/various-trailing-tabs/out.yaml000066400000000000000000000000231501576637100274610ustar00rootroot00000000000000a: b seq: - a c: d goccy-go-yaml-52dacb8/testdata/yaml-test-suite/whitespace-after-scalars-in-flow/000077500000000000000000000000001501576637100277775ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/whitespace-after-scalars-in-flow/in.json000066400000000000000000000001361501576637100313000ustar00rootroot00000000000000[ [ "a", "b", "c" ], { "a": "b", "c": "d", "e": "f" }, [] ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/whitespace-after-scalars-in-flow/in.yaml000066400000000000000000000001061501576637100312660ustar00rootroot00000000000000- [a, b , c ] - { "a" : b , c : 'd' , e : "f" } - [ ] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/whitespace-after-scalars-in-flow/out.yaml000066400000000000000000000000621501576637100314700ustar00rootroot00000000000000- - a - b - c - "a": b c: 'd' e: "f" - [] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/whitespace-around-colon-in-mappings/000077500000000000000000000000001501576637100305175ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/whitespace-around-colon-in-mappings/in.json000066400000000000000000000003411501576637100320160ustar00rootroot00000000000000{ "top1": { "key1": "scalar1" }, "top2": { "key2": "scalar2" }, "top3": { "scalar1": "scalar3" }, "top4": { "scalar2": "scalar4" }, "top5": "scalar5", "top6": { "key6": "scalar6" } } goccy-go-yaml-52dacb8/testdata/yaml-test-suite/whitespace-around-colon-in-mappings/in.yaml000066400000000000000000000003011501576637100320030ustar00rootroot00000000000000"top1" : "key1" : &alias1 scalar1 'top2' : 'key2' : &alias2 scalar2 top3: &node3 *alias1 : scalar3 top4: *alias2 : scalar4 top5 : scalar5 top6: &anchor6 'key6' : scalar6 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/whitespace-around-colon-in-mappings/out.yaml000066400000000000000000000002561501576637100322150ustar00rootroot00000000000000"top1": "key1": &alias1 scalar1 'top2': 'key2': &alias2 scalar2 top3: &node3 *alias1 : scalar3 top4: *alias2 : scalar4 top5: scalar5 top6: &anchor6 'key6': scalar6 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indendation-in-map/000077500000000000000000000000001501576637100263525ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indendation-in-map/error000066400000000000000000000000001501576637100274140ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indendation-in-map/in.yaml000066400000000000000000000000271501576637100276430ustar00rootroot00000000000000key: ok: 1 wrong: 2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indendation-in-mapping/000077500000000000000000000000001501576637100272305ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indendation-in-mapping/error000066400000000000000000000000001501576637100302720ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indendation-in-mapping/in.yaml000066400000000000000000000000171501576637100305200ustar00rootroot00000000000000k1: v1 k2: v2 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indendation-in-sequence/000077500000000000000000000000001501576637100274055ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indendation-in-sequence/error000066400000000000000000000000001501576637100304470ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indendation-in-sequence/in.yaml000066400000000000000000000000441501576637100306750ustar00rootroot00000000000000key: - ok - also ok - wrong goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indented-flow-sequence/000077500000000000000000000000001501576637100272445ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indented-flow-sequence/error000066400000000000000000000000001501576637100303060ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indented-flow-sequence/in.yaml000066400000000000000000000000241501576637100305320ustar00rootroot00000000000000--- flow: [a, b, c] goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indented-multiline-quoted-scalar/000077500000000000000000000000001501576637100312335ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indented-multiline-quoted-scalar/error000066400000000000000000000000001501576637100322750ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indented-multiline-quoted-scalar/in.yaml000066400000000000000000000000241501576637100325210ustar00rootroot00000000000000--- quoted: "a b c" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indented-sequence-item/000077500000000000000000000000001501576637100272335ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indented-sequence-item/error000066400000000000000000000000001501576637100302750ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/wrong-indented-sequence-item/in.yaml000066400000000000000000000000261501576637100305230ustar00rootroot00000000000000- key: value - item1 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/yaml-directive-without-document-end-marker/000077500000000000000000000000001501576637100320235ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/yaml-directive-without-document-end-marker/error000066400000000000000000000000001501576637100330650ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/yaml-directive-without-document-end-marker/in.yaml000066400000000000000000000000351501576637100333130ustar00rootroot00000000000000--- key: value %YAML 1.2 --- goccy-go-yaml-52dacb8/testdata/yaml-test-suite/yaml.go000066400000000000000000000034241501576637100230410ustar00rootroot00000000000000package yamltestsuite import ( "bytes" "encoding/json" "fmt" "io" "io/fs" "os" "path/filepath" "runtime" "sort" "strings" ) type TestSuite struct { Name string InYAML []byte InJSON []any OutYAML []byte Error bool } func curDir() string { _, file, _, _ := runtime.Caller(0) //nolint:dogsled return filepath.Dir(file) } func TestSuites() ([]*TestSuite, error) { dir := curDir() testMap := make(map[string]*TestSuite) if err := filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { if strings.HasSuffix(path, ".go") { // this file. return nil } if info.IsDir() { return nil } if err != nil { return err } name := strings.TrimPrefix(path, dir+"/") name = strings.TrimSuffix(name, "/"+filepath.Base(name)) if _, exists := testMap[name]; !exists { testMap[name] = &TestSuite{} } f, err := os.ReadFile(path) if err != nil { return err } fileName := filepath.Base(path) switch fileName { case "in.yaml": testMap[name].InYAML = f case "in.json": dec := json.NewDecoder(bytes.NewReader(f)) var inJSON []any for { var v any if err := dec.Decode(&v); err != nil { if err == io.EOF { break } return fmt.Errorf("failed to decode json: %s: %s: %w", name, string(f), err) } inJSON = append(inJSON, v) } testMap[name].InJSON = inJSON case "out.yaml": testMap[name].OutYAML = f case "error": testMap[name].Error = true } testMap[name].Name = name return nil }); err != nil { return nil, err } tests := make([]*TestSuite, 0, len(testMap)) for _, test := range testMap { if test.InYAML == nil { continue } tests = append(tests, test) } sort.Slice(tests, func(i, j int) bool { return tests[i].Name < tests[j].Name }) return tests, nil } zero-indented-block-scalar-with-line-that-looks-like-a-comment/000077500000000000000000000000001501576637100353515ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suitein.json000066400000000000000000000000351501576637100366500ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/zero-indented-block-scalar-with-line-that-looks-like-a-comment"line1 # no comment line3\n" in.yaml000066400000000000000000000000371501576637100366430ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/zero-indented-block-scalar-with-line-that-looks-like-a-comment--- > line1 # no comment line3 out.yaml000066400000000000000000000000411501576637100370370ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/zero-indented-block-scalar-with-line-that-looks-like-a-comment--- > line1 # no comment line3 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/zero-indented-block-scalar/000077500000000000000000000000001501576637100266475ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/zero-indented-block-scalar/in.json000066400000000000000000000000261501576637100301460ustar00rootroot00000000000000"line1 line2 line3\n" goccy-go-yaml-52dacb8/testdata/yaml-test-suite/zero-indented-block-scalar/in.yaml000066400000000000000000000000301501576637100301320ustar00rootroot00000000000000--- > line1 line2 line3 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/zero-indented-block-scalar/out.yaml000066400000000000000000000000321501576637100303350ustar00rootroot00000000000000--- > line1 line2 line3 goccy-go-yaml-52dacb8/testdata/yaml-test-suite/zero-indented-sequences-in-explicit-mapping-keys/000077500000000000000000000000001501576637100331325ustar00rootroot00000000000000in.yaml000066400000000000000000000000301501576637100343360ustar00rootroot00000000000000goccy-go-yaml-52dacb8/testdata/yaml-test-suite/zero-indented-sequences-in-explicit-mapping-keys--- ? - a - b : - c - d goccy-go-yaml-52dacb8/testdata/yaml_test.go000066400000000000000000000630361501576637100210370ustar00rootroot00000000000000package yaml_test import ( "bytes" "context" "errors" "strings" "testing" "github.com/google/go-cmp/cmp" "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/ast" ) func TestMarshal(t *testing.T) { var v struct { A int B string } v.A = 1 v.B = "hello" bytes, err := yaml.Marshal(v) if err != nil { t.Fatalf("%+v", err) } if string(bytes) != "a: 1\nb: hello\n" { t.Fatal("failed to marshal") } } func TestUnmarshal(t *testing.T) { yml := ` %YAML 1.2 --- a: 1 b: c ` var v struct { A int B string } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatalf("%+v", err) } } type marshalTest struct{} func (t *marshalTest) MarshalYAML() ([]byte, error) { return yaml.Marshal(yaml.MapSlice{ { "a", 1, }, { "b", "hello", }, { "c", true, }, { "d", map[string]string{"x": "y"}, }, }) } type marshalTest2 struct{} func (t *marshalTest2) MarshalYAML() (interface{}, error) { return yaml.MapSlice{ { "a", 2, }, { "b", "world", }, { "c", true, }, }, nil } func TestMarshalYAML(t *testing.T) { var v struct { A *marshalTest B *marshalTest2 } v.A = &marshalTest{} v.B = &marshalTest2{} bytes, err := yaml.Marshal(v) if err != nil { t.Fatalf("failed to Marshal: %+v", err) } expect := ` a: a: 1 b: hello c: true d: x: "y" b: a: 2 b: world c: true ` actual := "\n" + string(bytes) if expect != actual { t.Fatalf("failed to MarshalYAML expect:[%s], actual:[%s]", expect, actual) } } type unmarshalTest struct { a int b string c bool } func (t *unmarshalTest) UnmarshalYAML(b []byte) error { if t.a != 0 { return errors.New("unexpected field value to a") } if t.b != "" { return errors.New("unexpected field value to b") } if t.c { return errors.New("unexpected field value to c") } var v struct { A int B string C bool } if err := yaml.Unmarshal(b, &v); err != nil { return err } t.a = v.A t.b = v.B t.c = v.C return nil } type unmarshalTest2 struct { a int b string c bool } func (t *unmarshalTest2) UnmarshalYAML(unmarshal func(interface{}) error) error { var v struct { A int B string C bool } if t.a != 0 { return errors.New("unexpected field value to a") } if t.b != "" { return errors.New("unexpected field value to b") } if t.c { return errors.New("unexpected field value to c") } if err := unmarshal(&v); err != nil { return err } t.a = v.A t.b = v.B t.c = v.C return nil } func TestUnmarshalYAML(t *testing.T) { yml := ` a: a: 1 b: hello c: true b: a: 2 b: world c: true ` var v struct { A *unmarshalTest B *unmarshalTest2 } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatalf("failed to Unmarshal: %+v", err) } if v.A == nil { t.Fatal("failed to UnmarshalYAML") } if v.A.a != 1 { t.Fatal("failed to UnmarshalYAML") } if v.A.b != "hello" { t.Fatal("failed to UnmarshalYAML") } if !v.A.c { t.Fatal("failed to UnmarshalYAML") } if v.B == nil { t.Fatal("failed to UnmarshalYAML") } if v.B.a != 2 { t.Fatal("failed to UnmarshalYAML") } if v.B.b != "world" { t.Fatal("failed to UnmarshalYAML") } if !v.B.c { t.Fatal("failed to UnmarshalYAML") } } type ObjectMap map[string]*Object type ObjectDecl struct { Name string `yaml:"-"` *Object `yaml:",inline,anchor"` } func (m ObjectMap) MarshalYAML() (interface{}, error) { newMap := map[string]*ObjectDecl{} for k, v := range m { newMap[k] = &ObjectDecl{Name: k, Object: v} } return newMap, nil } type rootObject struct { Single ObjectMap `yaml:"single"` Collection map[string][]*Object `yaml:"collection"` } type Object struct { *Object `yaml:",omitempty,inline,alias"` MapValue map[string]interface{} `yaml:",omitempty,inline"` } func TestInlineAnchorAndAlias(t *testing.T) { yml := `--- single: default: &default id: 1 name: john user_1: &user_1 id: 1 name: ken user_2: &user_2 <<: *default id: 2 collection: defaults: - *default - <<: *default - <<: *default id: 2 users: - <<: *user_1 - <<: *user_2 - <<: *user_1 id: 3 - <<: *user_1 id: 4 - <<: *user_1 id: 5 ` var v rootObject if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } opt := yaml.MarshalAnchor(func(anchor *ast.AnchorNode, value interface{}) error { if o, ok := value.(*ObjectDecl); ok { return anchor.SetName(o.Name) } return nil }) var buf bytes.Buffer if err := yaml.NewEncoder(&buf, opt).Encode(v); err != nil { t.Fatalf("%+v", err) } actual := "---\n" + buf.String() if yml != actual { t.Fatalf("failed to marshal: expected:[%s] actual:[%s]", yml, actual) } } func TestMapSlice_Map(t *testing.T) { yml := ` a: b c: d ` var v yaml.MapSlice if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } m := v.ToMap() if len(m) != 2 { t.Fatal("failed to convert MapSlice to map") } if m["a"] != "b" { t.Fatal("failed to convert MapSlice to map") } if m["c"] != "d" { t.Fatal("failed to convert MapSlice to map") } } func TestMarshalWithModifiedAnchorAlias(t *testing.T) { yml := ` a: &a 1 b: *a ` var v struct { A *int `yaml:"a,anchor"` B *int `yaml:"b"` } if err := yaml.Unmarshal([]byte(yml), &v); err != nil { t.Fatal(err) } node, err := yaml.ValueToNode(v) if err != nil { t.Fatal(err) } anchors := ast.Filter(ast.AnchorType, node) if len(anchors) != 1 { t.Fatal("failed to filter node") } anchor, _ := anchors[0].(*ast.AnchorNode) if err := anchor.SetName("b"); err != nil { t.Fatal(err) } aliases := ast.Filter(ast.AliasType, node) if len(anchors) != 1 { t.Fatal("failed to filter node") } alias, _ := aliases[0].(*ast.AliasNode) if err := alias.SetName("b"); err != nil { t.Fatal(err) } expected := ` a: &b 1 b: *b` actual := "\n" + node.String() if expected != actual { t.Fatalf("failed to marshal: expected:[%q] but got [%q]", expected, actual) } } func Test_YAMLToJSON(t *testing.T) { yml := ` foo: bar: - a - b - c a: 1 ` actual, err := yaml.YAMLToJSON([]byte(yml)) if err != nil { t.Fatal(err) } expected := `{"foo": {"bar": ["a", "b", "c"]}, "a": 1}` if expected+"\n" != string(actual) { t.Fatalf("failed to convert yaml to json: expected [%q] but got [%q]", expected, actual) } } func Test_JSONToYAML(t *testing.T) { json := `{"foo": {"bar": ["a", "b", "c"]}, "a": 1}` expected := ` foo: bar: - a - b - c a: 1 ` actual, err := yaml.JSONToYAML([]byte(json)) if err != nil { t.Fatal(err) } if expected != "\n"+string(actual) { t.Fatalf("failed to convert json to yaml: expected [%q] but got [%q]", expected, actual) } } func Test_WithCommentOption(t *testing.T) { t.Run("line comment", func(t *testing.T) { v := struct { Foo string `yaml:"foo"` Bar map[string]interface{} `yaml:"bar"` Baz struct { X int `yaml:"x"` } `yaml:"baz"` }{ Foo: "aaa", Bar: map[string]interface{}{"bbb": "ccc"}, Baz: struct { X int `yaml:"x"` }{X: 10}, } b, err := yaml.MarshalWithOptions(v, yaml.WithComment( yaml.CommentMap{ "$.foo": []*yaml.Comment{yaml.LineComment("foo comment")}, "$.bar": []*yaml.Comment{yaml.LineComment("bar comment")}, "$.bar.bbb": []*yaml.Comment{yaml.LineComment("bbb comment")}, "$.baz.x": []*yaml.Comment{yaml.LineComment("x comment")}, }, )) if err != nil { t.Fatal(err) } expected := ` foo: aaa #foo comment bar: #bar comment bbb: ccc #bbb comment baz: x: 10 #x comment ` actual := "\n" + string(b) if expected != actual { t.Fatalf("expected:%s but got %s", expected, actual) } }) t.Run("line comment2", func(t *testing.T) { v := struct { Foo map[string]interface{} `yaml:"foo"` }{ Foo: map[string]interface{}{ "bar": map[string]interface{}{ "baz": true, }, }, } b, err := yaml.MarshalWithOptions(v, yaml.WithComment( yaml.CommentMap{ "$.foo.bar": []*yaml.Comment{yaml.HeadComment(" bar head comment"), yaml.LineComment(" bar line comment")}, "$.foo.bar.baz": []*yaml.Comment{yaml.LineComment(" baz line comment")}, }, )) if err != nil { t.Fatal(err) } expected := ` foo: # bar head comment bar: # bar line comment baz: true # baz line comment ` actual := "\n" + string(b) if expected != actual { t.Fatalf("expected:%s but got %s", expected, actual) } }) t.Run("single head comment", func(t *testing.T) { v := struct { Foo string `yaml:"foo"` Bar map[string]interface{} `yaml:"bar"` Baz struct { X int `yaml:"x"` } `yaml:"baz"` }{ Foo: "aaa", Bar: map[string]interface{}{"bbb": "ccc"}, Baz: struct { X int `yaml:"x"` }{X: 10}, } b, err := yaml.MarshalWithOptions(v, yaml.WithComment( yaml.CommentMap{ "$.foo": []*yaml.Comment{yaml.HeadComment("foo comment")}, "$.bar": []*yaml.Comment{yaml.HeadComment("bar comment")}, "$.bar.bbb": []*yaml.Comment{yaml.HeadComment("bbb comment")}, "$.baz.x": []*yaml.Comment{yaml.HeadComment("x comment")}, }, )) if err != nil { t.Fatal(err) } expected := ` #foo comment foo: aaa #bar comment bar: #bbb comment bbb: ccc baz: #x comment x: 10 ` actual := "\n" + string(b) if expected != actual { t.Fatalf("expected:%s but got %s", expected, actual) } }) t.Run("multiple head comment", func(t *testing.T) { v := struct { Foo string `yaml:"foo"` Bar map[string]interface{} `yaml:"bar"` Baz struct { X int `yaml:"x"` } `yaml:"baz"` }{ Foo: "aaa", Bar: map[string]interface{}{"bbb": "ccc"}, Baz: struct { X int `yaml:"x"` }{X: 10}, } b, err := yaml.MarshalWithOptions(v, yaml.WithComment( yaml.CommentMap{ "$.foo": []*yaml.Comment{ yaml.HeadComment( "foo comment", "foo comment2", ), }, "$.bar": []*yaml.Comment{ yaml.HeadComment( "bar comment", "bar comment2", ), }, "$.bar.bbb": []*yaml.Comment{ yaml.HeadComment( "bbb comment", "bbb comment2", ), }, "$.baz.x": []*yaml.Comment{ yaml.HeadComment( "x comment", "x comment2", ), }, }, )) if err != nil { t.Fatal(err) } expected := ` #foo comment #foo comment2 foo: aaa #bar comment #bar comment2 bar: #bbb comment #bbb comment2 bbb: ccc baz: #x comment #x comment2 x: 10 ` actual := "\n" + string(b) if expected != actual { t.Fatalf("expected:%s but got %s", expected, actual) } }) t.Run("foot comment", func(t *testing.T) { v := struct { Bar map[string]interface{} `yaml:"bar"` Baz []int `yaml:"baz"` }{ Bar: map[string]interface{}{"bbb": "ccc"}, Baz: []int{1, 2}, } b, err := yaml.MarshalWithOptions(v, yaml.IndentSequence(true), yaml.WithComment( yaml.CommentMap{ "$.bar.bbb": []*yaml.Comment{yaml.FootComment("ccc: ddd")}, "$.baz[1]": []*yaml.Comment{yaml.FootComment("- 3")}, "$.baz": []*yaml.Comment{yaml.FootComment(" foot comment", "foot comment2")}, }, )) if err != nil { t.Fatal(err) } expected := ` bar: bbb: ccc #ccc: ddd baz: - 1 - 2 #- 3 # foot comment #foot comment2 ` actual := "\n" + string(b) if expected != actual { t.Fatalf("expected:%s but got %s", expected, actual) } }) t.Run("combination", func(t *testing.T) { v := struct { Foo map[string]interface{} `yaml:"foo"` O map[string]interface{} `yaml:"o"` T map[string]bool `yaml:"t"` Bar map[string]interface{} `yaml:"bar"` Baz []int `yaml:"baz"` Hoge map[string]interface{} `yaml:"hoge"` }{ Foo: map[string]interface{}{ "a": map[string]interface{}{ "b": map[string]interface{}{ "c": "d", }, }, }, O: map[string]interface{}{ "p": map[string]interface{}{ "q": map[string]interface{}{ "r": "s", }, }, }, T: map[string]bool{ "u": true, }, Bar: map[string]interface{}{"bbb": "ccc"}, Baz: []int{1, 2}, Hoge: map[string]interface{}{ "moga": true, }, } b, err := yaml.MarshalWithOptions(v, yaml.IndentSequence(true), yaml.WithComment( yaml.CommentMap{ "$.foo": []*yaml.Comment{ yaml.HeadComment(" foo head comment", " foo head comment2"), yaml.LineComment(" foo line comment"), }, "$.foo.a": []*yaml.Comment{ yaml.HeadComment(" a head comment"), yaml.LineComment(" a line comment"), }, "$.foo.a.b": []*yaml.Comment{ yaml.HeadComment(" b head comment"), yaml.LineComment(" b line comment"), }, "$.foo.a.b.c": []*yaml.Comment{ yaml.LineComment(" c line comment"), }, "$.o": []*yaml.Comment{ yaml.LineComment(" o line comment"), }, "$.o.p": []*yaml.Comment{ yaml.HeadComment(" p head comment", " p head comment2"), yaml.LineComment(" p line comment"), }, "$.o.p.q": []*yaml.Comment{ yaml.HeadComment(" q head comment", " q head comment2"), yaml.LineComment(" q line comment"), }, "$.o.p.q.r": []*yaml.Comment{ yaml.LineComment(" r line comment"), }, "$.t.u": []*yaml.Comment{ yaml.LineComment(" u line comment"), }, "$.bar": []*yaml.Comment{ yaml.HeadComment(" bar head comment"), yaml.LineComment(" bar line comment"), }, "$.bar.bbb": []*yaml.Comment{ yaml.HeadComment(" bbb head comment"), yaml.LineComment(" bbb line comment"), yaml.FootComment(" bbb foot comment"), }, "$.baz[0]": []*yaml.Comment{ yaml.HeadComment(" sequence head comment"), yaml.LineComment(" sequence line comment"), }, "$.baz[1]": []*yaml.Comment{ yaml.HeadComment(" sequence head comment2"), yaml.LineComment(" sequence line comment2"), yaml.FootComment(" sequence foot comment"), }, "$.baz": []*yaml.Comment{ yaml.HeadComment(" baz head comment", " baz head comment2"), yaml.LineComment(" baz line comment"), yaml.FootComment(" baz foot comment"), }, "$.hoge.moga": []*yaml.Comment{ yaml.LineComment(" moga line comment"), yaml.FootComment(" moga foot comment"), }, }, )) if err != nil { t.Fatal(err) } expected := ` # foo head comment # foo head comment2 foo: # foo line comment # a head comment a: # a line comment # b head comment b: # b line comment c: d # c line comment o: # o line comment # p head comment # p head comment2 p: # p line comment # q head comment # q head comment2 q: # q line comment r: s # r line comment t: u: true # u line comment # bar head comment bar: # bar line comment # bbb head comment bbb: ccc # bbb line comment # bbb foot comment # baz head comment # baz head comment2 baz: # baz line comment # sequence head comment - 1 # sequence line comment # sequence head comment2 - 2 # sequence line comment2 # sequence foot comment # baz foot comment hoge: moga: true # moga line comment # moga foot comment ` actual := "\n" + string(b) if expected != actual { t.Fatalf("expected:%s but got %s", expected, actual) } }) } func Test_CommentToMapOption(t *testing.T) { type testCase struct { name string yml string options []yaml.DecodeOption expected []struct { path string comments []*yaml.Comment } } tests := []testCase{ { name: "line comment", yml: ` foo: aaa #foo comment bar: #bar comment bbb: ccc #bbb comment baz: x: 10 #x comment `, expected: []struct { path string comments []*yaml.Comment }{ {"$.foo", []*yaml.Comment{yaml.LineComment("foo comment")}}, {"$.bar", []*yaml.Comment{yaml.LineComment("bar comment")}}, {"$.bar.bbb", []*yaml.Comment{yaml.LineComment("bbb comment")}}, {"$.baz.x", []*yaml.Comment{yaml.LineComment("x comment")}}, }, }, { name: "line comment2", yml: ` foo: bar: baz # comment`, expected: []struct { path string comments []*yaml.Comment }{ {"$.foo.bar", []*yaml.Comment{yaml.LineComment(" comment")}}, }, }, { name: "single head comment", yml: ` #foo comment foo: aaa #bar comment bar: #bbb comment bbb: ccc baz: #x comment x: 10 `, expected: []struct { path string comments []*yaml.Comment }{ {"$.foo", []*yaml.Comment{yaml.HeadComment("foo comment")}}, {"$.bar", []*yaml.Comment{yaml.HeadComment("bar comment")}}, {"$.bar.bbb", []*yaml.Comment{yaml.HeadComment("bbb comment")}}, {"$.baz.x", []*yaml.Comment{yaml.HeadComment("x comment")}}, }, }, { name: "single head comment ordered map", yml: ` #first comment first: value #second comment second: #third comment third: value #forth comment forth: value #fifth comment fifth: #sixth comment sixth: value #seventh comment seventh: value `, expected: []struct { path string comments []*yaml.Comment }{ {"$.first", []*yaml.Comment{yaml.HeadComment("first comment")}}, {"$.second", []*yaml.Comment{yaml.HeadComment("second comment")}}, {"$.second.third", []*yaml.Comment{yaml.HeadComment("third comment")}}, {"$.second.forth", []*yaml.Comment{yaml.HeadComment("forth comment")}}, {"$.fifth", []*yaml.Comment{yaml.HeadComment("fifth comment")}}, {"$.fifth.sixth", []*yaml.Comment{yaml.HeadComment("sixth comment")}}, {"$.fifth.seventh", []*yaml.Comment{yaml.HeadComment("seventh comment")}}, }, options: []yaml.DecodeOption{yaml.UseOrderedMap()}, }, { name: "multiple head comments", yml: ` #foo comment #foo comment2 foo: aaa #bar comment #bar comment2 bar: #bbb comment #bbb comment2 bbb: ccc baz: #x comment #x comment2 x: 10 `, expected: []struct { path string comments []*yaml.Comment }{ {"$.foo", []*yaml.Comment{yaml.HeadComment("foo comment", "foo comment2")}}, {"$.bar", []*yaml.Comment{yaml.HeadComment("bar comment", "bar comment2")}}, {"$.bar.bbb", []*yaml.Comment{yaml.HeadComment("bbb comment", "bbb comment2")}}, {"$.baz.x", []*yaml.Comment{yaml.HeadComment("x comment", "x comment2")}}, }, }, { name: "foot comment", yml: ` bar: bbb: ccc #ccc: ddd baz: - 1 - 2 #- 3 # foot comment #foot comment2 `, expected: []struct { path string comments []*yaml.Comment }{ {"$.bar.bbb", []*yaml.Comment{yaml.FootComment("ccc: ddd")}}, {"$.baz[1]", []*yaml.Comment{yaml.FootComment("- 3")}}, {"$.baz", []*yaml.Comment{yaml.FootComment(" foot comment", "foot comment2")}}, }, }, { name: "combination", yml: ` # foo head comment # foo head comment2 foo: # foo line comment # a head comment a: # a line comment # b head comment b: # b line comment c: d # c line comment o: # o line comment # p head comment # p head comment2 p: # p line comment # q head comment # q head comment2 q: # q line comment r: s # r line comment t: u: true # u line comment # bar head comment bar: # bar line comment # bbb head comment bbb: ccc # bbb line comment # bbb foot comment # baz head comment # baz head comment2 baz: # baz line comment # sequence head comment - 1 # sequence line comment # sequence head comment2 - 2 # sequence line comment2 # sequence foot comment hoge: moga: true # moga line comment # moga foot comment # hoge foot comment `, expected: []struct { path string comments []*yaml.Comment }{ {"$.foo", []*yaml.Comment{yaml.HeadComment(" foo head comment", " foo head comment2"), yaml.LineComment(" foo line comment")}}, {"$.foo.a", []*yaml.Comment{yaml.HeadComment(" a head comment"), yaml.LineComment(" a line comment")}}, {"$.foo.a.b", []*yaml.Comment{yaml.HeadComment(" b head comment"), yaml.LineComment(" b line comment")}}, {"$.foo.a.b.c", []*yaml.Comment{yaml.LineComment(" c line comment")}}, {"$.o", []*yaml.Comment{yaml.LineComment(" o line comment")}}, {"$.o.p", []*yaml.Comment{yaml.HeadComment(" p head comment", " p head comment2"), yaml.LineComment(" p line comment")}}, {"$.o.p.q", []*yaml.Comment{yaml.HeadComment(" q head comment", " q head comment2"), yaml.LineComment(" q line comment")}}, {"$.o.p.q.r", []*yaml.Comment{yaml.LineComment(" r line comment")}}, {"$.t.u", []*yaml.Comment{yaml.LineComment(" u line comment")}}, {"$.bar", []*yaml.Comment{yaml.HeadComment(" bar head comment"), yaml.LineComment(" bar line comment")}}, {"$.bar.bbb", []*yaml.Comment{yaml.HeadComment(" bbb head comment"), yaml.LineComment(" bbb line comment"), yaml.FootComment(" bbb foot comment")}}, {"$.baz[0]", []*yaml.Comment{yaml.HeadComment(" sequence head comment"), yaml.LineComment(" sequence line comment")}}, {"$.baz[1]", []*yaml.Comment{yaml.HeadComment(" sequence head comment2"), yaml.LineComment(" sequence line comment2"), yaml.FootComment(" sequence foot comment")}}, {"$.baz", []*yaml.Comment{yaml.HeadComment(" baz head comment", " baz head comment2"), yaml.LineComment(" baz line comment")}}, {"$.hoge", []*yaml.Comment{yaml.FootComment(" hoge foot comment")}}, {"$.hoge.moga", []*yaml.Comment{yaml.LineComment(" moga line comment"), yaml.FootComment(" moga foot comment")}}, }, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { cm := yaml.CommentMap{} opts := []yaml.DecodeOption{yaml.CommentToMap(cm)} opts = append(opts, tc.options...) var v interface{} if err := yaml.UnmarshalWithOptions([]byte(tc.yml), &v, opts...); err != nil { t.Fatal(err) } if len(cm) != len(tc.expected) { t.Fatalf("comment size does not match: got: %d, expected: %d", len(cm), len(tc.expected)) } for _, exp := range tc.expected { comments := cm[exp.path] if comments == nil { t.Fatalf("failed to get path %s", exp.path) } if diff := cmp.Diff(exp.comments, comments); diff != "" { t.Errorf("(-got, +want)\n%s", diff) } } }) } } func TestCommentMapRoundTrip(t *testing.T) { // test that an unmarshal and marshal round trip retains comments. // if expect is empty, the test will use the input as the expected result. tests := []struct { name string source string expect string encodeOptions []yaml.EncodeOption }{ { name: "simple map", source: ` # head a: 1 # line # foot `, }, { name: "nesting", source: ` - 1 # one - foo: a: b # c comment c: d # d comment "e#f": g # g comment h.i: j # j comment "k.#l": m # m comment `, }, { name: "single quotes", source: `'a#b': c # c comment`, encodeOptions: []yaml.EncodeOption{yaml.UseSingleQuote(true)}, }, { name: "single quotes added in encode", source: `a#b: c # c comment`, encodeOptions: []yaml.EncodeOption{yaml.UseSingleQuote(true)}, expect: `'a#b': c # c comment`, }, { name: "double quotes quotes transformed to single quotes", source: `"a#b": c # c comment`, encodeOptions: []yaml.EncodeOption{yaml.UseSingleQuote(true)}, expect: `'a#b': c # c comment`, }, { name: "single quotes quotes transformed to double quotes", source: `'a#b': c # c comment`, expect: `"a#b": c # c comment`, }, { name: "single quotes removed", source: `'a': b # b comment`, expect: `a: b # b comment`, }, { name: "double quotes removed", source: `"a": b # b comment`, expect: `a: b # b comment`, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { var val any cm := yaml.CommentMap{} source := strings.TrimSpace(test.source) if err := yaml.UnmarshalWithOptions([]byte(source), &val, yaml.CommentToMap(cm)); err != nil { t.Fatalf("%+v", err) } marshaled, err := yaml.MarshalWithOptions(val, append(test.encodeOptions, yaml.WithComment(cm))...) if err != nil { t.Fatalf("%+v", err) } got := strings.TrimSpace(string(marshaled)) expect := strings.TrimSpace(test.expect) if expect == "" { expect = source } if got != expect { t.Fatalf("expected:\n%s\ngot:\n%s\n", expect, got) } }) } } func TestRegisterCustomMarshaler(t *testing.T) { type T struct { Foo []byte `yaml:"foo"` } yaml.RegisterCustomMarshaler[T](func(_ T) ([]byte, error) { return []byte(`"override"`), nil }) b, err := yaml.Marshal(&T{Foo: []byte("bar")}) if err != nil { t.Fatal(err) } if !bytes.Equal(b, []byte("\"override\"\n")) { t.Fatalf("failed to register custom marshaler. got: %q", b) } } func TestRegisterCustomMarshalerContext(t *testing.T) { type T struct { Foo []byte `yaml:"foo"` } yaml.RegisterCustomMarshalerContext[T](func(ctx context.Context, _ T) ([]byte, error) { if ctx.Value("plop") != uint(42) { t.Fatalf("context value is not correct") } return []byte(`"override"`), nil }) ctx := context.WithValue(context.Background(), "plop", uint(42)) b, err := yaml.MarshalContext(ctx, &T{Foo: []byte("bar")}) if err != nil { t.Fatal(err) } if !bytes.Equal(b, []byte("\"override\"\n")) { t.Fatalf("failed to register custom marshaler. got: %q", b) } } func TestRegisterCustomUnmarshaler(t *testing.T) { type T struct { Foo []byte `yaml:"foo"` } yaml.RegisterCustomUnmarshaler[T](func(v *T, _ []byte) error { v.Foo = []byte("override") return nil }) var v T if err := yaml.Unmarshal([]byte(`"foo": "bar"`), &v); err != nil { t.Fatal(err) } if !bytes.Equal(v.Foo, []byte("override")) { t.Fatalf("failed to decode. got %q", v.Foo) } } func TestRegisterCustomUnmarshalerContext(t *testing.T) { type T struct { Foo []byte `yaml:"foo"` } yaml.RegisterCustomUnmarshalerContext[T](func(ctx context.Context, v *T, _ []byte) error { if ctx.Value("plop") != uint(42) { t.Fatalf("context value is not correct") } v.Foo = []byte("override") return nil }) var v T ctx := context.WithValue(context.Background(), "plop", uint(42)) if err := yaml.UnmarshalContext(ctx, []byte(`"foo": "bar"`), &v); err != nil { t.Fatal(err) } if !bytes.Equal(v.Foo, []byte("override")) { t.Fatalf("failed to decode. got %q", v.Foo) } } goccy-go-yaml-52dacb8/token/000077500000000000000000000000001501576637100160065ustar00rootroot00000000000000goccy-go-yaml-52dacb8/token/token.go000066400000000000000000000715071501576637100174670ustar00rootroot00000000000000package token import ( "errors" "fmt" "strconv" "strings" "time" ) // Character type for character type Character byte const ( // SequenceEntryCharacter character for sequence entry SequenceEntryCharacter Character = '-' // MappingKeyCharacter character for mapping key MappingKeyCharacter Character = '?' // MappingValueCharacter character for mapping value MappingValueCharacter Character = ':' // CollectEntryCharacter character for collect entry CollectEntryCharacter Character = ',' // SequenceStartCharacter character for sequence start SequenceStartCharacter Character = '[' // SequenceEndCharacter character for sequence end SequenceEndCharacter Character = ']' // MappingStartCharacter character for mapping start MappingStartCharacter Character = '{' // MappingEndCharacter character for mapping end MappingEndCharacter Character = '}' // CommentCharacter character for comment CommentCharacter Character = '#' // AnchorCharacter character for anchor AnchorCharacter Character = '&' // AliasCharacter character for alias AliasCharacter Character = '*' // TagCharacter character for tag TagCharacter Character = '!' // LiteralCharacter character for literal LiteralCharacter Character = '|' // FoldedCharacter character for folded FoldedCharacter Character = '>' // SingleQuoteCharacter character for single quote SingleQuoteCharacter Character = '\'' // DoubleQuoteCharacter character for double quote DoubleQuoteCharacter Character = '"' // DirectiveCharacter character for directive DirectiveCharacter Character = '%' // SpaceCharacter character for space SpaceCharacter Character = ' ' // LineBreakCharacter character for line break LineBreakCharacter Character = '\n' ) // Type type identifier for token type Type int const ( // UnknownType reserve for invalid type UnknownType Type = iota // DocumentHeaderType type for DocumentHeader token DocumentHeaderType // DocumentEndType type for DocumentEnd token DocumentEndType // SequenceEntryType type for SequenceEntry token SequenceEntryType // MappingKeyType type for MappingKey token MappingKeyType // MappingValueType type for MappingValue token MappingValueType // MergeKeyType type for MergeKey token MergeKeyType // CollectEntryType type for CollectEntry token CollectEntryType // SequenceStartType type for SequenceStart token SequenceStartType // SequenceEndType type for SequenceEnd token SequenceEndType // MappingStartType type for MappingStart token MappingStartType // MappingEndType type for MappingEnd token MappingEndType // CommentType type for Comment token CommentType // AnchorType type for Anchor token AnchorType // AliasType type for Alias token AliasType // TagType type for Tag token TagType // LiteralType type for Literal token LiteralType // FoldedType type for Folded token FoldedType // SingleQuoteType type for SingleQuote token SingleQuoteType // DoubleQuoteType type for DoubleQuote token DoubleQuoteType // DirectiveType type for Directive token DirectiveType // SpaceType type for Space token SpaceType // NullType type for Null token NullType // ImplicitNullType type for implicit Null token. // This is used when explicit keywords such as null or ~ are not specified. // It is distinguished during encoding and output as an empty string. ImplicitNullType // InfinityType type for Infinity token InfinityType // NanType type for Nan token NanType // IntegerType type for Integer token IntegerType // BinaryIntegerType type for BinaryInteger token BinaryIntegerType // OctetIntegerType type for OctetInteger token OctetIntegerType // HexIntegerType type for HexInteger token HexIntegerType // FloatType type for Float token FloatType // StringType type for String token StringType // BoolType type for Bool token BoolType // InvalidType type for invalid token InvalidType ) // String type identifier to text func (t Type) String() string { switch t { case UnknownType: return "Unknown" case DocumentHeaderType: return "DocumentHeader" case DocumentEndType: return "DocumentEnd" case SequenceEntryType: return "SequenceEntry" case MappingKeyType: return "MappingKey" case MappingValueType: return "MappingValue" case MergeKeyType: return "MergeKey" case CollectEntryType: return "CollectEntry" case SequenceStartType: return "SequenceStart" case SequenceEndType: return "SequenceEnd" case MappingStartType: return "MappingStart" case MappingEndType: return "MappingEnd" case CommentType: return "Comment" case AnchorType: return "Anchor" case AliasType: return "Alias" case TagType: return "Tag" case LiteralType: return "Literal" case FoldedType: return "Folded" case SingleQuoteType: return "SingleQuote" case DoubleQuoteType: return "DoubleQuote" case DirectiveType: return "Directive" case SpaceType: return "Space" case StringType: return "String" case BoolType: return "Bool" case IntegerType: return "Integer" case BinaryIntegerType: return "BinaryInteger" case OctetIntegerType: return "OctetInteger" case HexIntegerType: return "HexInteger" case FloatType: return "Float" case NullType: return "Null" case ImplicitNullType: return "ImplicitNull" case InfinityType: return "Infinity" case NanType: return "Nan" case InvalidType: return "Invalid" } return "" } // CharacterType type for character category type CharacterType int const ( // CharacterTypeIndicator type of indicator character CharacterTypeIndicator CharacterType = iota // CharacterTypeWhiteSpace type of white space character CharacterTypeWhiteSpace // CharacterTypeMiscellaneous type of miscellaneous character CharacterTypeMiscellaneous // CharacterTypeEscaped type of escaped character CharacterTypeEscaped // CharacterTypeInvalid type for a invalid token. CharacterTypeInvalid ) // String character type identifier to text func (c CharacterType) String() string { switch c { case CharacterTypeIndicator: return "Indicator" case CharacterTypeWhiteSpace: return "WhiteSpace" case CharacterTypeMiscellaneous: return "Miscellaneous" case CharacterTypeEscaped: return "Escaped" } return "" } // Indicator type for indicator type Indicator int const ( // NotIndicator not indicator NotIndicator Indicator = iota // BlockStructureIndicator indicator for block structure ( '-', '?', ':' ) BlockStructureIndicator // FlowCollectionIndicator indicator for flow collection ( '[', ']', '{', '}', ',' ) FlowCollectionIndicator // CommentIndicator indicator for comment ( '#' ) CommentIndicator // NodePropertyIndicator indicator for node property ( '!', '&', '*' ) NodePropertyIndicator // BlockScalarIndicator indicator for block scalar ( '|', '>' ) BlockScalarIndicator // QuotedScalarIndicator indicator for quoted scalar ( ''', '"' ) QuotedScalarIndicator // DirectiveIndicator indicator for directive ( '%' ) DirectiveIndicator // InvalidUseOfReservedIndicator indicator for invalid use of reserved keyword ( '@', '`' ) InvalidUseOfReservedIndicator ) // String indicator to text func (i Indicator) String() string { switch i { case NotIndicator: return "NotIndicator" case BlockStructureIndicator: return "BlockStructure" case FlowCollectionIndicator: return "FlowCollection" case CommentIndicator: return "Comment" case NodePropertyIndicator: return "NodeProperty" case BlockScalarIndicator: return "BlockScalar" case QuotedScalarIndicator: return "QuotedScalar" case DirectiveIndicator: return "Directive" case InvalidUseOfReservedIndicator: return "InvalidUseOfReserved" } return "" } var ( reservedNullKeywords = []string{ "null", "Null", "NULL", "~", } reservedBoolKeywords = []string{ "true", "True", "TRUE", "false", "False", "FALSE", } // For compatibility with other YAML 1.1 parsers // Note that we use these solely for encoding the bool value with quotes. // go-yaml should not treat these as reserved keywords at parsing time. // as go-yaml is supposed to be compliant only with YAML 1.2. reservedLegacyBoolKeywords = []string{ "y", "Y", "yes", "Yes", "YES", "n", "N", "no", "No", "NO", "on", "On", "ON", "off", "Off", "OFF", } reservedInfKeywords = []string{ ".inf", ".Inf", ".INF", "-.inf", "-.Inf", "-.INF", } reservedNanKeywords = []string{ ".nan", ".NaN", ".NAN", } reservedKeywordMap = map[string]func(string, string, *Position) *Token{} // reservedEncKeywordMap contains is the keyword map used at encoding time. // This is supposed to be a superset of reservedKeywordMap, // and used to quote legacy keywords present in YAML 1.1 or lesser for compatibility reasons, // even though this library is supposed to be YAML 1.2-compliant. reservedEncKeywordMap = map[string]func(string, string, *Position) *Token{} ) func reservedKeywordToken(typ Type, value, org string, pos *Position) *Token { return &Token{ Type: typ, CharacterType: CharacterTypeMiscellaneous, Indicator: NotIndicator, Value: value, Origin: org, Position: pos, } } func init() { for _, keyword := range reservedNullKeywords { f := func(value, org string, pos *Position) *Token { return reservedKeywordToken(NullType, value, org, pos) } reservedKeywordMap[keyword] = f reservedEncKeywordMap[keyword] = f } for _, keyword := range reservedBoolKeywords { f := func(value, org string, pos *Position) *Token { return reservedKeywordToken(BoolType, value, org, pos) } reservedKeywordMap[keyword] = f reservedEncKeywordMap[keyword] = f } for _, keyword := range reservedLegacyBoolKeywords { reservedEncKeywordMap[keyword] = func(value, org string, pos *Position) *Token { return reservedKeywordToken(BoolType, value, org, pos) } } for _, keyword := range reservedInfKeywords { reservedKeywordMap[keyword] = func(value, org string, pos *Position) *Token { return reservedKeywordToken(InfinityType, value, org, pos) } } for _, keyword := range reservedNanKeywords { reservedKeywordMap[keyword] = func(value, org string, pos *Position) *Token { return reservedKeywordToken(NanType, value, org, pos) } } } // ReservedTagKeyword type of reserved tag keyword type ReservedTagKeyword string const ( // IntegerTag `!!int` tag IntegerTag ReservedTagKeyword = "!!int" // FloatTag `!!float` tag FloatTag ReservedTagKeyword = "!!float" // NullTag `!!null` tag NullTag ReservedTagKeyword = "!!null" // SequenceTag `!!seq` tag SequenceTag ReservedTagKeyword = "!!seq" // MappingTag `!!map` tag MappingTag ReservedTagKeyword = "!!map" // StringTag `!!str` tag StringTag ReservedTagKeyword = "!!str" // BinaryTag `!!binary` tag BinaryTag ReservedTagKeyword = "!!binary" // OrderedMapTag `!!omap` tag OrderedMapTag ReservedTagKeyword = "!!omap" // SetTag `!!set` tag SetTag ReservedTagKeyword = "!!set" // TimestampTag `!!timestamp` tag TimestampTag ReservedTagKeyword = "!!timestamp" // BooleanTag `!!bool` tag BooleanTag ReservedTagKeyword = "!!bool" // MergeTag `!!merge` tag MergeTag ReservedTagKeyword = "!!merge" ) var ( // ReservedTagKeywordMap map for reserved tag keywords ReservedTagKeywordMap = map[ReservedTagKeyword]func(string, string, *Position) *Token{ IntegerTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, FloatTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, NullTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, SequenceTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, MappingTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, StringTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, BinaryTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, OrderedMapTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, SetTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, TimestampTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, BooleanTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, MergeTag: func(value, org string, pos *Position) *Token { return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } }, } ) type NumberType string const ( NumberTypeDecimal NumberType = "decimal" NumberTypeBinary NumberType = "binary" NumberTypeOctet NumberType = "octet" NumberTypeHex NumberType = "hex" NumberTypeFloat NumberType = "float" ) type NumberValue struct { Type NumberType Value any Text string } func ToNumber(value string) *NumberValue { num, err := toNumber(value) if err != nil { return nil } return num } func isNumber(value string) bool { num, err := toNumber(value) if err != nil { var numErr *strconv.NumError if errors.As(err, &numErr) && errors.Is(numErr.Err, strconv.ErrRange) { return true } return false } return num != nil } func toNumber(value string) (*NumberValue, error) { if len(value) == 0 { return nil, nil } if strings.HasPrefix(value, "_") { return nil, nil } dotCount := strings.Count(value, ".") if dotCount > 1 { return nil, nil } isNegative := strings.HasPrefix(value, "-") normalized := strings.ReplaceAll(strings.TrimPrefix(strings.TrimPrefix(value, "+"), "-"), "_", "") var ( typ NumberType base int ) switch { case strings.HasPrefix(normalized, "0x"): normalized = strings.TrimPrefix(normalized, "0x") base = 16 typ = NumberTypeHex case strings.HasPrefix(normalized, "0o"): normalized = strings.TrimPrefix(normalized, "0o") base = 8 typ = NumberTypeOctet case strings.HasPrefix(normalized, "0b"): normalized = strings.TrimPrefix(normalized, "0b") base = 2 typ = NumberTypeBinary case strings.HasPrefix(normalized, "0") && len(normalized) > 1 && dotCount == 0: base = 8 typ = NumberTypeOctet case dotCount == 1: typ = NumberTypeFloat default: typ = NumberTypeDecimal base = 10 } text := normalized if isNegative { text = "-" + text } var v any if typ == NumberTypeFloat { f, err := strconv.ParseFloat(text, 64) if err != nil { return nil, err } v = f } else if isNegative { i, err := strconv.ParseInt(text, base, 64) if err != nil { return nil, err } v = i } else { u, err := strconv.ParseUint(text, base, 64) if err != nil { return nil, err } v = u } return &NumberValue{ Type: typ, Value: v, Text: text, }, nil } // This is a subset of the formats permitted by the regular expression // defined at http://yaml.org/type/timestamp.html. Note that time.Parse // cannot handle: "2001-12-14 21:59:43.10 -5" from the examples. var timestampFormats = []string{ time.RFC3339Nano, "2006-01-02t15:04:05.999999999Z07:00", // RFC3339Nano with lower-case "t". time.DateTime, time.DateOnly, // Not in examples, but to preserve backward compatibility by quoting time values. "15:4", } func isTimestamp(value string) bool { for _, format := range timestampFormats { if _, err := time.Parse(format, value); err == nil { return true } } return false } // IsNeedQuoted checks whether the value needs quote for passed string or not func IsNeedQuoted(value string) bool { if value == "" { return true } if _, exists := reservedEncKeywordMap[value]; exists { return true } if isNumber(value) { return true } if value == "-" { return true } first := value[0] switch first { case '*', '&', '[', '{', '}', ']', ',', '!', '|', '>', '%', '\'', '"', '@', ' ', '`': return true } last := value[len(value)-1] switch last { case ':', ' ': return true } if isTimestamp(value) { return true } for i, c := range value { switch c { case '#', '\\': return true case ':', '-': if i+1 < len(value) && value[i+1] == ' ' { return true } } } return false } // LiteralBlockHeader detect literal block scalar header func LiteralBlockHeader(value string) string { lbc := DetectLineBreakCharacter(value) switch { case !strings.Contains(value, lbc): return "" case strings.HasSuffix(value, fmt.Sprintf("%s%s", lbc, lbc)): return "|+" case strings.HasSuffix(value, lbc): return "|" default: return "|-" } } // New create reserved keyword token or number token and other string token. func New(value string, org string, pos *Position) *Token { fn := reservedKeywordMap[value] if fn != nil { return fn(value, org, pos) } if num := ToNumber(value); num != nil { tk := &Token{ Type: IntegerType, CharacterType: CharacterTypeMiscellaneous, Indicator: NotIndicator, Value: value, Origin: org, Position: pos, } switch num.Type { case NumberTypeFloat: tk.Type = FloatType case NumberTypeBinary: tk.Type = BinaryIntegerType case NumberTypeOctet: tk.Type = OctetIntegerType case NumberTypeHex: tk.Type = HexIntegerType } return tk } return String(value, org, pos) } // Position type for position in YAML document type Position struct { Line int Column int Offset int IndentNum int IndentLevel int } // String position to text func (p *Position) String() string { return fmt.Sprintf("[level:%d,line:%d,column:%d,offset:%d]", p.IndentLevel, p.Line, p.Column, p.Offset) } // Token type for token type Token struct { // Type is a token type. Type Type // CharacterType is a character type. CharacterType CharacterType // Indicator is a indicator type. Indicator Indicator // Value is a string extracted with only meaningful characters, with spaces and such removed. Value string // Origin is a string that stores the original text as-is. Origin string // Error keeps error message for InvalidToken. Error string // Position is a token position. Position *Position // Next is a next token reference. Next *Token // Prev is a previous token reference. Prev *Token } // PreviousType previous token type func (t *Token) PreviousType() Type { if t.Prev != nil { return t.Prev.Type } return UnknownType } // NextType next token type func (t *Token) NextType() Type { if t.Next != nil { return t.Next.Type } return UnknownType } // AddColumn append column number to current position of column func (t *Token) AddColumn(col int) { if t == nil { return } t.Position.Column += col } // Clone copy token ( preserve Prev/Next reference ) func (t *Token) Clone() *Token { if t == nil { return nil } copied := *t if t.Position != nil { pos := *(t.Position) copied.Position = &pos } return &copied } // Dump outputs token information to stdout for debugging. func (t *Token) Dump() { fmt.Printf( "[TYPE]:%q [CHARTYPE]:%q [INDICATOR]:%q [VALUE]:%q [ORG]:%q [POS(line:column:level:offset)]: %d:%d:%d:%d\n", t.Type, t.CharacterType, t.Indicator, t.Value, t.Origin, t.Position.Line, t.Position.Column, t.Position.IndentLevel, t.Position.Offset, ) } // Tokens type of token collection type Tokens []*Token func (t Tokens) InvalidToken() *Token { for _, tt := range t { if tt.Type == InvalidType { return tt } } return nil } func (t *Tokens) add(tk *Token) { tokens := *t if len(tokens) == 0 { tokens = append(tokens, tk) } else { last := tokens[len(tokens)-1] last.Next = tk tk.Prev = last tokens = append(tokens, tk) } *t = tokens } // Add append new some tokens func (t *Tokens) Add(tks ...*Token) { for _, tk := range tks { t.add(tk) } } // Dump dump all token structures for debugging func (t Tokens) Dump() { for _, tk := range t { fmt.Print("- ") tk.Dump() } } // String create token for String func String(value string, org string, pos *Position) *Token { return &Token{ Type: StringType, CharacterType: CharacterTypeMiscellaneous, Indicator: NotIndicator, Value: value, Origin: org, Position: pos, } } // SequenceEntry create token for SequenceEntry func SequenceEntry(org string, pos *Position) *Token { return &Token{ Type: SequenceEntryType, CharacterType: CharacterTypeIndicator, Indicator: BlockStructureIndicator, Value: string(SequenceEntryCharacter), Origin: org, Position: pos, } } // MappingKey create token for MappingKey func MappingKey(pos *Position) *Token { return &Token{ Type: MappingKeyType, CharacterType: CharacterTypeIndicator, Indicator: BlockStructureIndicator, Value: string(MappingKeyCharacter), Origin: string(MappingKeyCharacter), Position: pos, } } // MappingValue create token for MappingValue func MappingValue(pos *Position) *Token { return &Token{ Type: MappingValueType, CharacterType: CharacterTypeIndicator, Indicator: BlockStructureIndicator, Value: string(MappingValueCharacter), Origin: string(MappingValueCharacter), Position: pos, } } // CollectEntry create token for CollectEntry func CollectEntry(org string, pos *Position) *Token { return &Token{ Type: CollectEntryType, CharacterType: CharacterTypeIndicator, Indicator: FlowCollectionIndicator, Value: string(CollectEntryCharacter), Origin: org, Position: pos, } } // SequenceStart create token for SequenceStart func SequenceStart(org string, pos *Position) *Token { return &Token{ Type: SequenceStartType, CharacterType: CharacterTypeIndicator, Indicator: FlowCollectionIndicator, Value: string(SequenceStartCharacter), Origin: org, Position: pos, } } // SequenceEnd create token for SequenceEnd func SequenceEnd(org string, pos *Position) *Token { return &Token{ Type: SequenceEndType, CharacterType: CharacterTypeIndicator, Indicator: FlowCollectionIndicator, Value: string(SequenceEndCharacter), Origin: org, Position: pos, } } // MappingStart create token for MappingStart func MappingStart(org string, pos *Position) *Token { return &Token{ Type: MappingStartType, CharacterType: CharacterTypeIndicator, Indicator: FlowCollectionIndicator, Value: string(MappingStartCharacter), Origin: org, Position: pos, } } // MappingEnd create token for MappingEnd func MappingEnd(org string, pos *Position) *Token { return &Token{ Type: MappingEndType, CharacterType: CharacterTypeIndicator, Indicator: FlowCollectionIndicator, Value: string(MappingEndCharacter), Origin: org, Position: pos, } } // Comment create token for Comment func Comment(value string, org string, pos *Position) *Token { return &Token{ Type: CommentType, CharacterType: CharacterTypeIndicator, Indicator: CommentIndicator, Value: value, Origin: org, Position: pos, } } // Anchor create token for Anchor func Anchor(org string, pos *Position) *Token { return &Token{ Type: AnchorType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: string(AnchorCharacter), Origin: org, Position: pos, } } // Alias create token for Alias func Alias(org string, pos *Position) *Token { return &Token{ Type: AliasType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: string(AliasCharacter), Origin: org, Position: pos, } } // Tag create token for Tag func Tag(value string, org string, pos *Position) *Token { fn := ReservedTagKeywordMap[ReservedTagKeyword(value)] if fn != nil { return fn(value, org, pos) } return &Token{ Type: TagType, CharacterType: CharacterTypeIndicator, Indicator: NodePropertyIndicator, Value: value, Origin: org, Position: pos, } } // Literal create token for Literal func Literal(value string, org string, pos *Position) *Token { return &Token{ Type: LiteralType, CharacterType: CharacterTypeIndicator, Indicator: BlockScalarIndicator, Value: value, Origin: org, Position: pos, } } // Folded create token for Folded func Folded(value string, org string, pos *Position) *Token { return &Token{ Type: FoldedType, CharacterType: CharacterTypeIndicator, Indicator: BlockScalarIndicator, Value: value, Origin: org, Position: pos, } } // SingleQuote create token for SingleQuote func SingleQuote(value string, org string, pos *Position) *Token { return &Token{ Type: SingleQuoteType, CharacterType: CharacterTypeIndicator, Indicator: QuotedScalarIndicator, Value: value, Origin: org, Position: pos, } } // DoubleQuote create token for DoubleQuote func DoubleQuote(value string, org string, pos *Position) *Token { return &Token{ Type: DoubleQuoteType, CharacterType: CharacterTypeIndicator, Indicator: QuotedScalarIndicator, Value: value, Origin: org, Position: pos, } } // Directive create token for Directive func Directive(org string, pos *Position) *Token { return &Token{ Type: DirectiveType, CharacterType: CharacterTypeIndicator, Indicator: DirectiveIndicator, Value: string(DirectiveCharacter), Origin: org, Position: pos, } } // Space create token for Space func Space(pos *Position) *Token { return &Token{ Type: SpaceType, CharacterType: CharacterTypeWhiteSpace, Indicator: NotIndicator, Value: string(SpaceCharacter), Origin: string(SpaceCharacter), Position: pos, } } // MergeKey create token for MergeKey func MergeKey(org string, pos *Position) *Token { return &Token{ Type: MergeKeyType, CharacterType: CharacterTypeMiscellaneous, Indicator: NotIndicator, Value: "<<", Origin: org, Position: pos, } } // DocumentHeader create token for DocumentHeader func DocumentHeader(org string, pos *Position) *Token { return &Token{ Type: DocumentHeaderType, CharacterType: CharacterTypeMiscellaneous, Indicator: NotIndicator, Value: "---", Origin: org, Position: pos, } } // DocumentEnd create token for DocumentEnd func DocumentEnd(org string, pos *Position) *Token { return &Token{ Type: DocumentEndType, CharacterType: CharacterTypeMiscellaneous, Indicator: NotIndicator, Value: "...", Origin: org, Position: pos, } } func Invalid(err string, org string, pos *Position) *Token { return &Token{ Type: InvalidType, CharacterType: CharacterTypeInvalid, Indicator: NotIndicator, Value: org, Origin: org, Error: err, Position: pos, } } // DetectLineBreakCharacter detect line break character in only one inside scalar content scope. func DetectLineBreakCharacter(src string) string { nc := strings.Count(src, "\n") rc := strings.Count(src, "\r") rnc := strings.Count(src, "\r\n") switch { case nc == rnc && rc == rnc: return "\r\n" case rc > nc: return "\r" default: return "\n" } } goccy-go-yaml-52dacb8/token/token_test.go000066400000000000000000000070611501576637100205200ustar00rootroot00000000000000package token_test import ( "testing" "github.com/goccy/go-yaml/token" ) func TestToken(t *testing.T) { pos := &token.Position{} tokens := token.Tokens{ token.SequenceEntry("-", pos), token.MappingKey(pos), token.MappingValue(pos), token.CollectEntry(",", pos), token.SequenceStart("[", pos), token.SequenceEnd("]", pos), token.MappingStart("{", pos), token.MappingEnd("}", pos), token.Comment("#", "#", pos), token.Anchor("&", pos), token.Alias("*", pos), token.Literal("|", "|", pos), token.Folded(">", ">", pos), token.SingleQuote("'", "'", pos), token.DoubleQuote(`"`, `"`, pos), token.Directive("%", pos), token.Space(pos), token.MergeKey("<<", pos), token.DocumentHeader("---", pos), token.DocumentEnd("...", pos), token.New("1", "1", pos), token.New("3.14", "3.14", pos), token.New("-0b101010", "-0b101010", pos), token.New("0xA", "0xA", pos), token.New("685.230_15e+03", "685.230_15e+03", pos), token.New("02472256", "02472256", pos), token.New("0o2472256", "0o2472256", pos), token.New("", "", pos), token.New("_1", "_1", pos), token.New("1.1.1.1", "1.1.1.1", pos), token.New("+", "+", pos), token.New("-", "-", pos), token.New("_", "_", pos), token.New("~", "~", pos), token.New("true", "true", pos), token.New("false", "false", pos), token.New(".nan", ".nan", pos), token.New(".inf", ".inf", pos), token.New("-.inf", "-.inf", pos), token.New("null", "null", pos), token.Tag("!!null", "!!null", pos), token.Tag("!!map", "!!map", pos), token.Tag("!!str", "!!str", pos), token.Tag("!!seq", "!!seq", pos), token.Tag("!!binary", "!!binary", pos), token.Tag("!!omap", "!!omap", pos), token.Tag("!!set", "!!set", pos), token.Tag("!!int", "!!int", pos), token.Tag("!!float", "!!float", pos), token.Tag("!hoge", "!hoge", pos), } tokens.Dump() tokens.Add(token.New("hoge", "hoge", pos)) if tokens[len(tokens)-1].PreviousType() != token.TagType { t.Fatal("invalid previous token type") } if tokens[0].PreviousType() != token.UnknownType { t.Fatal("invalid previous token type") } if tokens[len(tokens)-2].NextType() != token.StringType { t.Fatal("invalid next token type") } if tokens[len(tokens)-1].NextType() != token.UnknownType { t.Fatal("invalid next token type") } } func TestIsNeedQuoted(t *testing.T) { needQuotedTests := []string{ "", "true", "1.234", "0b11111111111111111111111111111111111111111111111111111111111111111", "0o7777777777777777777777777777777777777777", "999999999999999999999999999999999999999999", "0xffffffffffffffffffffffffffffffffffffffff", "1:1", "2001-12-15T02:59:43.1Z", "2001-12-14t21:59:43.10-05:00", "2001-12-15 2:59:43.10", "2002-12-14", "hoge # comment", "\\0", "#a b", "*a b", "&a b", "{a b", "}a b", "[a b", "]a b", ",a b", "!a b", "|a b", ">a b", ">a b", "%a b", `'a b`, `"a b`, "a:", "a: b", "y", "Y", "yes", "Yes", "YES", "n", "N", "no", "No", "NO", "on", "On", "ON", "off", "Off", "OFF", "@test", " a", " a ", "a ", "null", "Null", "NULL", "~", "-", "- --foo", } for i, test := range needQuotedTests { if !token.IsNeedQuoted(test) { t.Errorf("%d: failed to quoted judge for %s", i, test) } } notNeedQuotedTests := []string{ "Hello World", // time.Parse cannot handle: "2001-12-14 21:59:43.10 -5" from the examples. // https://yaml.org/type/timestamp.html "2001-12-14 21:59:43.10 -5", } for i, test := range notNeedQuotedTests { if token.IsNeedQuoted(test) { t.Errorf("%d: failed to quoted judge for %s", i, test) } } } goccy-go-yaml-52dacb8/validate.go000066400000000000000000000006261501576637100170120ustar00rootroot00000000000000package yaml // StructValidator need to implement Struct method only // ( see https://pkg.go.dev/github.com/go-playground/validator/v10#Validate.Struct ) type StructValidator interface { Struct(interface{}) error } // FieldError need to implement StructField method only // ( see https://pkg.go.dev/github.com/go-playground/validator/v10#FieldError ) type FieldError interface { StructField() string } goccy-go-yaml-52dacb8/yaml.go000066400000000000000000000300141501576637100161550ustar00rootroot00000000000000package yaml import ( "bytes" "context" "io" "reflect" "sync" "github.com/goccy/go-yaml/ast" "github.com/goccy/go-yaml/internal/errors" ) // BytesMarshaler interface may be implemented by types to customize their // behavior when being marshaled into a YAML document. The returned value // is marshaled in place of the original value implementing Marshaler. // // If an error is returned by MarshalYAML, the marshaling procedure stops // and returns with the provided error. type BytesMarshaler interface { MarshalYAML() ([]byte, error) } // BytesMarshalerContext interface use BytesMarshaler with context.Context. type BytesMarshalerContext interface { MarshalYAML(context.Context) ([]byte, error) } // InterfaceMarshaler interface has MarshalYAML compatible with github.com/go-yaml/yaml package. type InterfaceMarshaler interface { MarshalYAML() (interface{}, error) } // InterfaceMarshalerContext interface use InterfaceMarshaler with context.Context. type InterfaceMarshalerContext interface { MarshalYAML(context.Context) (interface{}, error) } // BytesUnmarshaler interface may be implemented by types to customize their // behavior when being unmarshaled from a YAML document. type BytesUnmarshaler interface { UnmarshalYAML([]byte) error } // BytesUnmarshalerContext interface use BytesUnmarshaler with context.Context. type BytesUnmarshalerContext interface { UnmarshalYAML(context.Context, []byte) error } // InterfaceUnmarshaler interface has UnmarshalYAML compatible with github.com/go-yaml/yaml package. type InterfaceUnmarshaler interface { UnmarshalYAML(func(interface{}) error) error } // InterfaceUnmarshalerContext interface use InterfaceUnmarshaler with context.Context. type InterfaceUnmarshalerContext interface { UnmarshalYAML(context.Context, func(interface{}) error) error } // NodeUnmarshaler interface is similar to BytesUnmarshaler but provide related AST node instead of raw YAML source. type NodeUnmarshaler interface { UnmarshalYAML(ast.Node) error } // NodeUnmarshalerContext interface is similar to BytesUnmarshaler but provide related AST node instead of raw YAML source. type NodeUnmarshalerContext interface { UnmarshalYAML(context.Context, ast.Node) error } // MapItem is an item in a MapSlice. type MapItem struct { Key, Value interface{} } // MapSlice encodes and decodes as a YAML map. // The order of keys is preserved when encoding and decoding. type MapSlice []MapItem // ToMap convert to map[interface{}]interface{}. func (s MapSlice) ToMap() map[interface{}]interface{} { v := map[interface{}]interface{}{} for _, item := range s { v[item.Key] = item.Value } return v } // Marshal serializes the value provided into a YAML document. The structure // of the generated document will reflect the structure of the value itself. // Maps and pointers (to struct, string, int, etc) are accepted as the in value. // // Struct fields are only marshaled if they are exported (have an upper case // first letter), and are marshaled using the field name lowercased as the // default key. Custom keys may be defined via the "yaml" name in the field // tag: the content preceding the first comma is used as the key, and the // following comma-separated options are used to tweak the marshaling process. // Conflicting names result in a runtime error. // // The field tag format accepted is: // // `(...) yaml:"[][,[,]]" (...)` // // The following flags are currently supported: // // omitempty Only include the field if it's not set to the zero // value for the type or to empty slices or maps. // Zero valued structs will be omitted if all their public // fields are zero, unless they implement an IsZero // method (see the IsZeroer interface type), in which // case the field will be included if that method returns true. // Note that this definition is slightly different from the Go's // encoding/json 'omitempty' definition. It combines some elements // of 'omitempty' and 'omitzero'. See https://github.com/goccy/go-yaml/issues/695. // // omitzero The omitzero tag behaves in the same way as the interpretation of the omitzero tag in the encoding/json library. // 1) If the field type has an "IsZero() bool" method, that will be used to determine whether the value is zero. // 2) Otherwise, the value is zero if it is the zero value for its type. // // flow Marshal using a flow style (useful for structs, // sequences and maps). // // inline Inline the field, which must be a struct or a map, // causing all of its fields or keys to be processed as if // they were part of the outer struct. For maps, keys must // not conflict with the yaml keys of other struct fields. // // anchor Marshal with anchor. If want to define anchor name explicitly, use anchor=name style. // Otherwise, if used 'anchor' name only, used the field name lowercased as the anchor name // // alias Marshal with alias. If want to define alias name explicitly, use alias=name style. // Otherwise, If omitted alias name and the field type is pointer type, // assigned anchor name automatically from same pointer address. // // In addition, if the key is "-", the field is ignored. // // For example: // // type T struct { // F int `yaml:"a,omitempty"` // B int // } // yaml.Marshal(&T{B: 2}) // Returns "b: 2\n" // yaml.Marshal(&T{F: 1}) // Returns "a: 1\nb: 0\n" func Marshal(v interface{}) ([]byte, error) { return MarshalWithOptions(v) } // MarshalWithOptions serializes the value provided into a YAML document with EncodeOptions. func MarshalWithOptions(v interface{}, opts ...EncodeOption) ([]byte, error) { return MarshalContext(context.Background(), v, opts...) } // MarshalContext serializes the value provided into a YAML document with context.Context and EncodeOptions. func MarshalContext(ctx context.Context, v interface{}, opts ...EncodeOption) ([]byte, error) { var buf bytes.Buffer if err := NewEncoder(&buf, opts...).EncodeContext(ctx, v); err != nil { return nil, err } return buf.Bytes(), nil } // ValueToNode convert from value to ast.Node. func ValueToNode(v interface{}, opts ...EncodeOption) (ast.Node, error) { var buf bytes.Buffer node, err := NewEncoder(&buf, opts...).EncodeToNode(v) if err != nil { return nil, err } return node, nil } // Unmarshal decodes the first document found within the in byte slice // and assigns decoded values into the out value. // // Struct fields are only unmarshalled if they are exported (have an // upper case first letter), and are unmarshalled using the field name // lowercased as the default key. Custom keys may be defined via the // "yaml" name in the field tag: the content preceding the first comma // is used as the key, and the following comma-separated options are // used to tweak the marshaling process (see Marshal). // Conflicting names result in a runtime error. // // For example: // // type T struct { // F int `yaml:"a,omitempty"` // B int // } // var t T // yaml.Unmarshal([]byte("a: 1\nb: 2"), &t) // // See the documentation of Marshal for the format of tags and a list of // supported tag options. func Unmarshal(data []byte, v interface{}) error { return UnmarshalWithOptions(data, v) } // UnmarshalWithOptions decodes with DecodeOptions the first document found within the in byte slice // and assigns decoded values into the out value. func UnmarshalWithOptions(data []byte, v interface{}, opts ...DecodeOption) error { return UnmarshalContext(context.Background(), data, v, opts...) } // UnmarshalContext decodes with context.Context and DecodeOptions. func UnmarshalContext(ctx context.Context, data []byte, v interface{}, opts ...DecodeOption) error { dec := NewDecoder(bytes.NewBuffer(data), opts...) if err := dec.DecodeContext(ctx, v); err != nil { if err == io.EOF { return nil } return err } return nil } // NodeToValue converts node to the value pointed to by v. func NodeToValue(node ast.Node, v interface{}, opts ...DecodeOption) error { var buf bytes.Buffer if err := NewDecoder(&buf, opts...).DecodeFromNode(node, v); err != nil { return err } return nil } // FormatError is a utility function that takes advantage of the metadata // stored in the errors returned by this package's parser. // // If the second argument `colored` is true, the error message is colorized. // If the third argument `inclSource` is true, the error message will // contain snippets of the YAML source that was used. func FormatError(e error, colored, inclSource bool) string { var yamlErr Error if errors.As(e, &yamlErr) { return yamlErr.FormatError(colored, inclSource) } return e.Error() } // YAMLToJSON convert YAML bytes to JSON. func YAMLToJSON(bytes []byte) ([]byte, error) { var v interface{} if err := UnmarshalWithOptions(bytes, &v, UseOrderedMap()); err != nil { return nil, err } out, err := MarshalWithOptions(v, JSON()) if err != nil { return nil, err } return out, nil } // JSONToYAML convert JSON bytes to YAML. func JSONToYAML(bytes []byte) ([]byte, error) { var v interface{} if err := UnmarshalWithOptions(bytes, &v, UseOrderedMap()); err != nil { return nil, err } out, err := Marshal(v) if err != nil { return nil, err } return out, nil } var ( globalCustomMarshalerMu sync.Mutex globalCustomUnmarshalerMu sync.Mutex globalCustomMarshalerMap = map[reflect.Type]func(context.Context, interface{}) ([]byte, error){} globalCustomUnmarshalerMap = map[reflect.Type]func(context.Context, interface{}, []byte) error{} ) // RegisterCustomMarshaler overrides any encoding process for the type specified in generics. // If you want to switch the behavior for each encoder, use `CustomMarshaler` defined as EncodeOption. // // NOTE: If type T implements MarshalYAML for pointer receiver, the type specified in RegisterCustomMarshaler must be *T. // If RegisterCustomMarshaler and CustomMarshaler of EncodeOption are specified for the same type, // the CustomMarshaler specified in EncodeOption takes precedence. func RegisterCustomMarshaler[T any](marshaler func(T) ([]byte, error)) { globalCustomMarshalerMu.Lock() defer globalCustomMarshalerMu.Unlock() var typ T globalCustomMarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}) ([]byte, error) { return marshaler(v.(T)) } } // RegisterCustomMarshalerContext overrides any encoding process for the type specified in generics. // Similar to RegisterCustomMarshalerContext, but allows passing a context to the unmarshaler function. func RegisterCustomMarshalerContext[T any](marshaler func(context.Context, T) ([]byte, error)) { globalCustomMarshalerMu.Lock() defer globalCustomMarshalerMu.Unlock() var typ T globalCustomMarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}) ([]byte, error) { return marshaler(ctx, v.(T)) } } // RegisterCustomUnmarshaler overrides any decoding process for the type specified in generics. // If you want to switch the behavior for each decoder, use `CustomUnmarshaler` defined as DecodeOption. // // NOTE: If RegisterCustomUnmarshaler and CustomUnmarshaler of DecodeOption are specified for the same type, // the CustomUnmarshaler specified in DecodeOption takes precedence. func RegisterCustomUnmarshaler[T any](unmarshaler func(*T, []byte) error) { globalCustomUnmarshalerMu.Lock() defer globalCustomUnmarshalerMu.Unlock() var typ *T globalCustomUnmarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}, b []byte) error { return unmarshaler(v.(*T), b) } } // RegisterCustomUnmarshalerContext overrides any decoding process for the type specified in generics. // Similar to RegisterCustomUnmarshalerContext, but allows passing a context to the unmarshaler function. func RegisterCustomUnmarshalerContext[T any](unmarshaler func(context.Context, *T, []byte) error) { globalCustomUnmarshalerMu.Lock() defer globalCustomUnmarshalerMu.Unlock() var typ *T globalCustomUnmarshalerMap[reflect.TypeOf(typ)] = func(ctx context.Context, v interface{}, b []byte) error { return unmarshaler(ctx, v.(*T), b) } } goccy-go-yaml-52dacb8/yaml_test.go000066400000000000000000000073771501576637100172340ustar00rootroot00000000000000package yaml_test import ( "fmt" "io" "reflect" "strings" "testing" "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/parser" ) func TestRoundTripWithComment(t *testing.T) { yml := ` # head comment key: value # line comment ` var v struct { Key string } comments := yaml.CommentMap{} if err := yaml.UnmarshalWithOptions([]byte(yml), &v, yaml.Strict(), yaml.CommentToMap(comments)); err != nil { t.Fatal(err) } out, err := yaml.MarshalWithOptions(v, yaml.WithComment(comments)) if err != nil { t.Fatal(err) } got := "\n" + string(out) if yml != got { t.Fatalf("failed to get round tripped yaml: %s", got) } } func TestStreamDecodingWithComment(t *testing.T) { yml := ` # comment --- a: b: c: # comment --- foo: bar # comment --- - a - b - c # comment ` cm := yaml.CommentMap{} dec := yaml.NewDecoder(strings.NewReader(yml), yaml.CommentToMap(cm)) var commentPathsWithDocIndex [][]string for { var v any if err := dec.Decode(&v); err != nil { if err == io.EOF { break } t.Fatal(err) } paths := make([]string, 0, len(cm)) for k := range cm { paths = append(paths, k) } commentPathsWithDocIndex = append(commentPathsWithDocIndex, paths) for k := range cm { delete(cm, k) } } if !reflect.DeepEqual(commentPathsWithDocIndex, [][]string{ {"$.a.b.c"}, {"$.foo"}, {"$[2]"}, }) { t.Fatalf("failed to get comment: %v", commentPathsWithDocIndex) } } func TestDecodeKeepAddress(t *testing.T) { var data = ` a: &a [_] b: &b [*a,*a] c: &c [*b,*b] d: &d [*c,*c] ` var v map[string]any if err := yaml.Unmarshal([]byte(data), &v); err != nil { t.Fatal(err) } a := v["a"] b := v["b"] for _, vv := range v["b"].([]any) { if fmt.Sprintf("%p", a) != fmt.Sprintf("%p", vv) { t.Fatalf("failed to decode b element as keep address") } } for _, vv := range v["c"].([]any) { if fmt.Sprintf("%p", b) != fmt.Sprintf("%p", vv) { t.Fatalf("failed to decode c element as keep address") } } } func TestSmartAnchor(t *testing.T) { var data = ` a: &a [_,_,_,_,_,_,_,_,_,_,_,_,_,_,_] b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a,*a] c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b,*b] d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c,*c] e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d,*d] f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e,*e] g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f,*f] h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g,*g] i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h,*h] ` var v any if err := yaml.Unmarshal([]byte(data), &v); err != nil { t.Fatal(err) } got, err := yaml.MarshalWithOptions(v, yaml.WithSmartAnchor()) if err != nil { t.Fatal(err) } expected := ` a: &a - _ - _ - _ - _ - _ - _ - _ - _ - _ - _ - _ - _ - _ - _ - _ b: &b - *a - *a - *a - *a - *a - *a - *a - *a - *a - *a c: &c - *b - *b - *b - *b - *b - *b - *b - *b - *b - *b d: &d - *c - *c - *c - *c - *c - *c - *c - *c - *c - *c e: &e - *d - *d - *d - *d - *d - *d - *d - *d - *d - *d f: &f - *e - *e - *e - *e - *e - *e - *e - *e - *e - *e g: &g - *f - *f - *f - *f - *f - *f - *f - *f - *f - *f h: &h - *g - *g - *g - *g - *g - *g - *g - *g - *g - *g i: - *h - *h - *h - *h - *h - *h - *h - *h - *h - *h ` if strings.TrimPrefix(expected, "\n") != string(got) { t.Fatalf("failed to encode: %s", string(got)) } } func TestCustomErrorMessage(t *testing.T) { data := ` foo: bar: foo: 2 baz: foo: 3 foo: 2 ` if _, err := parser.ParseBytes([]byte(data), 0); err == nil { t.Fatalf("expected error") } else { yamlErr, ok := err.(yaml.Error) if !ok { t.Fatalf("failed to get yaml.Error from error: %T", err) } expected := ` [7:1] custom message 4 | foo: 2 5 | baz: 6 | foo: 3 > 7 | foo: 2 ^ ` got := "\n" + yaml.FormatErrorWithToken("custom message", yamlErr.GetToken(), false, true) if expected != got { t.Fatalf("unexpected error message:\nexpected:\n%s\nbut got:\n%s", expected, got) } } } goccy-go-yaml-52dacb8/yaml_test_suite_test.go000066400000000000000000000107751501576637100215000ustar00rootroot00000000000000//go:build !windows package yaml_test import ( "bytes" "encoding/json" "io" "runtime/debug" "testing" "github.com/goccy/go-yaml" "github.com/goccy/go-yaml/testdata/yaml-test-suite" ) var failureTestNames = []string{ "anchors-on-empty-scalars", // no json. "aliases-in-flow-objects", // no json. "aliases-in-explicit-block-mapping", // no json. "block-mapping-with-missing-keys", // no json. "empty-implicit-key-in-single-pair-flow-sequences", // no json. "empty-keys-in-block-and-flow-mapping", // no json. "empty-lines-at-end-of-document", // no json. "flow-mapping-separate-values", // no json. "flow-sequence-in-flow-mapping", // no json. "implicit-flow-mapping-key-on-one-line", // no json. "mapping-key-and-flow-sequence-item-anchors", // no json. "nested-implicit-complex-keys", // no json. "question-mark-edge-cases/00", // no json. "question-mark-edge-cases/01", // no json. "single-character-streams/01", // no json. "single-pair-implicit-entries", // no json. "spec-example-2-11-mapping-between-sequences", // no json. "spec-example-6-12-separation-spaces", // no json. "spec-example-7-16-flow-mapping-entries", // no json. "spec-example-7-3-completely-empty-flow-nodes", // no json. "spec-example-8-18-implicit-block-mapping-entries", // no json. "spec-example-8-19-compact-block-mappings", // no json. "syntax-character-edge-cases/00", // no json. "tags-on-empty-scalars", // no json. "various-combinations-of-explicit-block-mappings", // no json. "various-trailing-comments", // no json. "various-trailing-comments-1-3", // no json. "zero-indented-sequences-in-explicit-mapping-keys", // no json. "colon-at-the-beginning-of-adjacent-flow-scalar", "comment-without-whitespace-after-doublequoted-scalar", "construct-binary", "dash-in-flow-sequence", "flow-collections-over-many-lines/01", "flow-mapping-colon-on-line-after-key/02", "invalid-comment-after-comma", "invalid-comment-after-end-of-flow-sequence", "invalid-comma-in-tag", "plain-dashes-in-flow-sequence", "spec-example-9-3-bare-documents", "spec-example-9-6-stream", "spec-example-9-6-stream-1-3", "tabs-in-various-contexts/003", "tabs-that-look-like-indentation/04", "tag-shorthand-used-in-documents-but-only-defined-in-the-first", "trailing-line-of-spaces/01", // last '\n' character is needed ? "wrong-indented-flow-sequence", // error ? "wrong-indented-multiline-quoted-scalar", // error ? } var failureTestNameMap map[string]struct{} func init() { failureTestNameMap = make(map[string]struct{}) for _, name := range failureTestNames { failureTestNameMap[name] = struct{}{} } } func TestYAMLTestSuite(t *testing.T) { tests, err := yamltestsuite.TestSuites() if err != nil { t.Fatal(err) } for _, test := range tests { if _, exists := failureTestNameMap[test.Name]; exists { continue } t.Run(test.Name, func(t *testing.T) { defer func() { if e := recover(); e != nil { t.Fatalf("panic occurred.\n[input]\n%s\nstack[%s]", string(test.InYAML), debug.Stack()) } }() if test.Error { var v any if err := yaml.Unmarshal(test.InYAML, &v); err == nil { t.Fatalf("expected error.\n[input]\n%s\n", string(test.InYAML)) } return } dec := yaml.NewDecoder(bytes.NewReader(test.InYAML)) var idx int for { var v any if err := dec.Decode(&v); err != nil { if err == io.EOF { break } t.Fatal(err) } if len(test.InJSON) <= idx { t.Fatalf("expected json value is nothing but got %v", v) } expected, err := json.Marshal(test.InJSON[idx]) if err != nil { t.Fatalf("failed to encode json value: %v", err) } got, err := json.Marshal(v) if err != nil { t.Fatalf("failed to encode json value: %v", err) } if !bytes.Equal(expected, got) { t.Fatalf("json mismatch [%s]:\n[expected]\n%s\n[got]\n%s\n", test.Name, string(expected), string(got)) } idx++ } }) } total := len(tests) failed := len(failureTestNames) passed := total - failed passedRate := float32(passed) / float32(total) * 100 t.Logf("total:[%d] passed:[%d] failure:[%d] passedRate:[%f%%]", total, passed, failed, passedRate) }