Skip to content

Commit

Permalink
Add yaml_decode to stdlib (#927)
Browse files Browse the repository at this point in the history
* Implement yaml_decode with thanks to @djcode for most of the work.

* Update docs/sources/reference/stdlib/yaml_decode.md

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>

---------

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>
  • Loading branch information
mattdurham and clayton-cornell committed May 25, 2024
1 parent a30cc8a commit 3631969
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Main (unreleased)
- Improved filesystem error handling when working with `loki.source.file` and `local.file_match`,
which removes some false-positive error log messages on Windows (@thampiotr)

- Add `yaml_decode` to standard library. (@mattdurham, @djcode)

### Bugfixes

- Fix panic when component ID contains `/` in `otelcomponent.MustNewType(ID)`.(@qclaogui)
Expand Down
39 changes: 39 additions & 0 deletions docs/sources/reference/stdlib/yaml_decode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
canonical: https://grafana.com/docs/alloy/latest/reference/stdlib/yaml_decode/
description: Learn about yaml_decode
title: yaml_decode
---

# yaml_decode

The `yaml_decode` function decodes a string representing YAML into an {{< param "PRODUCT_NAME" >}}
value. `yaml_decode` fails if the string argument provided cannot be parsed as
YAML.

A common use case of `yaml_decode` is to decode the output of a
[`local.file`][] component to an {{< param "PRODUCT_NAME" >}} value.

{{< admonition type="note" >}}
Remember to escape double quotes when passing YAML string literals to `yaml_decode`.

For example, the YAML value `key: "value"` is properly represented by the string `"key: \"value\""`.
{{< /admonition >}}

## Examples

```
> yaml_decode("15")
15
> yaml_decode("[1, 2, 3]")
[1, 2, 3]
> yaml_decode("null")
null
> yaml_decode("key: value")
{
key = "value",
}
> yaml_decode(local.file.some_file.content)
"Hello, world!"
```

[`local.file`]: ../../components/local.file/
10 changes: 10 additions & 0 deletions syntax/internal/stdlib/stdlib.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/grafana/alloy/syntax/internal/value"
"github.com/ohler55/ojg/jp"
"github.com/ohler55/ojg/oj"
"gopkg.in/yaml.v3"
)

// Identifiers holds a list of stdlib identifiers by name. All interface{}
Expand Down Expand Up @@ -83,6 +84,15 @@ var Identifiers = map[string]interface{}{
return res, nil
},

"yaml_decode": func(in string) (interface{}, error) {
var res interface{}
err := yaml.Unmarshal([]byte(in), &res)
if err != nil {
return nil, err
}
return res, nil
},

"json_path": func(jsonString string, path string) (interface{}, error) {
jsonPathExpr, err := jp.ParseString(path)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions syntax/vm/vm_stdlib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ func TestVM_Stdlib(t *testing.T) {
{"json_decode array", `json_decode("[0, 1, 2]")`, []interface{}{float64(0), float64(1), float64(2)}},
{"json_decode nil field", `json_decode("{\"foo\": null}")`, map[string]interface{}{"foo": nil}},
{"json_decode nil array element", `json_decode("[0, null]")`, []interface{}{float64(0), nil}},
{"yaml_decode object", "yaml_decode(`foo: bar`)", map[string]interface{}{"foo": "bar"}},
{"yaml_decode array", "yaml_decode(`[0, 1, 2]`)", []interface{}{0, 1, 2}},
{"yaml_decode array float", "yaml_decode(`[0.0, 1.0, 2.0]`)", []interface{}{float64(0), float64(1), float64(2)}},
{"yaml_decode nil field", "yaml_decode(`foo: null`)", map[string]interface{}{"foo": nil}},
{"yaml_decode nil array element", `yaml_decode("[0, null]")`, []interface{}{0, nil}},
}

for _, tc := range tt {
Expand Down

0 comments on commit 3631969

Please sign in to comment.