-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: json.RawMessage equivalent #13
Comments
I would like to +1 this. Would be very useful for writing config files in my projects! |
Yeah I am missing that too so I can delay the actual decoding of some fields. |
+1 for yaml.RawMessage edit The |
+1 for yaml.RawMessage |
The problem with yaml.RawMessage is that unlike JSON, YAML is context-dependent. One cannot properly encode a piece of raw YAML without knowing what the surrounding data is, due to indentation. Can the +1 voters please detail a bit how this is intended to be used that isn't solved by the current system? Maybe we can design something else that solves the problem. |
@niemeyer The problem I had intended to solve using I think most problems people intend to solve with a |
@niemeyer In my case, I have a lot of yaml configuration files, each includes some common definition and plugin settings, for plugin settings it's variant from plugin to plugin, i want to delay the parse and pass the RawMessage to leave the plugin implementation do it. |
I have the exact same use case as @missedone |
Yeah, it should be easy to use a MapSlice, and one can even marshal it back into yaml and then unmarshal it again to get the exact semantics of a RawMessage. That said, I'll keep this issue open so we can consider the idea of a RawMessage-like feature further. |
Thanks for all the feedback, by the way! |
It would be great if you could just have a method mapping a MapSlice (or a plain |
@dvirsky That goes beyond the goals of the yaml package, but there are other packages available for such direct map-to-struct conversion (e.g. https://github.com/mitchellh/mapstructure). |
Isn't it enough to implement type RawMessage struct {
unmarshal func(interface{}) error
}
func (msg *RawMessage) UnmarshalYAML(unmarshal func(interface{}) error) error {
msg.unmarshal = unmarshal
return nil
}
func (msg *RawMessage) Unmarshal(v interace{}) error {
return msg.unmarshal(v)
} Then you can call |
Yes, that's similar to what bson.Raw does, but it's not quite the same, and it's not the same as It's likely the direction we'll take, though. We'll just need some further work on the marshaling side. |
True, I only needed to defer unmarshalling, was not really thinking about marshalling, but sure, it's obviously not symmetrical. |
And not very "Raw", if you see what I mean. We'll likely end up with a similar abstraction that can lazily unmarshal and re-marshal appropriately, but not provide direct access to the text. |
Yep. |
Are there any good examples of how to use |
What I wanted to use
Using only topdata := make(map[string]interface{})
foodata := make(map[string]interface{})
topdata["foo"] = foodata
foodata["bar"] = json.RawMessage(`{ "a" : 1 }`)
foodata["baz"] = map[string]interface{}{ "b" : 2 }
enc, _ := yaml.Marshal(topdata)
println(enc) Instead, the json.RawMessage seems to be interpreted as a slice of bytes and each byte output as an integer element. This package should at least support some way of doing the output above. As far as I can tell it isn't possible right now. |
I have some ideas for how this might work. It's possible that the YAML equivalent of json.RawMessage might be a parsed sequence of YAML "events" (e.g map start, scalar, sequence end, etc) which can then potentially be marshaled and unmarshaled in a context-insensitive way. |
+1 |
not sure if this is going to help, but we started doing this in our case:
basically use |
@pete911 this is a good idea, this might work for me, thanks ! However, a type json.RawMessage like (which would most likely be named yaml.RawMessage) would be welcomed. |
+1 |
+1 |
I've just tried the method proposed by @tchap and it worked perfectly! If this could be included into the official yaml package, then the need for the RawMessage just goes away, at least from my side :) |
You can define a string field for such a RawMessage. Then, in your yaml file, write a multi-line string as value of that field. reference: https://stackoverflow.com/a/21699210/1033539 |
+1 |
@niemeyer Any status of this feature? |
We won't have a RawMessage because unlike json yaml is context and indentation sensitive, so we can't just write out some string as-is without pre-processing. That said, with v3 we have yaml.Node, which offers something convenient for preserving more of the structure of some document. |
@niemeyer thanks for responding! Not so cool to hear that, but i hope third version of this package will help a lot with dynamic typed configs. Also thanks a lot for this lib! You're doing amazing job 😃 |
I came upon this problem today, and it is easily solvable. I solved it for myself within the consuming package but it could be a nice addition to the main repository. However I know that PRs are not generally accepted or reviewed so maybe I will add it to my fork, but for all those who want a solution, simply we want to use the Here is a full working example: package main
import (
"fmt"
"gopkg.in/yaml.v3"
)
func main() {
data := `key: raw message equivalent complete!`
var target map[string]RawNode
if err := yaml.Unmarshal([]byte(data), &target); err != nil {
panic(err)
}
var str string
if err := target["key"].Decode(&str); err != nil {
panic(err)
}
fmt.Println(str) // Print: raw message equivalent complete!
}
type RawNode struct{ *yaml.Node }
func (n *RawNode) UnmarshalYAML(node *yaml.Node) error {
n.Node = node
return nil
} |
It would be great to have sth. similar to http://golang.org/pkg/encoding/json/#RawMessage.
I'm using go-yaml in http://github.com/michaelsauter/crane and would like to unmarshal the JSON/YAML partially (to provide defaults for objects inside arrays).
The text was updated successfully, but these errors were encountered: