Skip to content

Commit

Permalink
Expose a ToJSON and runtime.YAMLDecoder helper
Browse files Browse the repository at this point in the history
Enables clients to optionally handle YAML
  • Loading branch information
smarterclayton committed Mar 20, 2015
1 parent 022c103 commit 71abc99
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
36 changes: 36 additions & 0 deletions pkg/runtime/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,47 @@ limitations under the License.

package runtime

import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/yaml"
)

// CodecFor returns a Codec that invokes Encode with the provided version.
func CodecFor(scheme *Scheme, version string) Codec {
return &codecWrapper{scheme, version}
}

// yamlCodec converts YAML passed to the Decoder methods to JSON.
type yamlCodec struct {
// a Codec for JSON
Codec
}

// yamlCodec implements Codec
var _ Codec = yamlCodec{}

// YAMLDecoder adds YAML decoding support to a codec that supports JSON.
func YAMLDecoder(codec Codec) Codec {
return &yamlCodec{codec}
}

func (c yamlCodec) Decode(data []byte) (Object, error) {
out, err := yaml.ToJSON(data)
if err != nil {
return nil, err
}
data = out
return c.Codec.Decode(data)
}

func (c yamlCodec) DecodeInto(data []byte, obj Object) error {
out, err := yaml.ToJSON(data)
if err != nil {
return err
}
data = out
return c.Codec.DecodeInto(data, obj)
}

// EncodeOrDie is a version of Encode which will panic instead of returning an error. For tests.
func EncodeOrDie(codec Codec, obj Object) string {
bytes, err := codec.Encode(obj)
Expand Down
23 changes: 21 additions & 2 deletions pkg/util/yaml/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ import (
"github.com/golang/glog"
)

// ToJSON converts a single YAML document into a JSON document
// or returns an error. If the document appears to be JSON the
// YAML decoding path is not used (so that error messages are)
// JSON specific.
func ToJSON(data []byte) ([]byte, error) {
if hasJSONPrefix(data) {
return data, nil
}
return yaml.YAMLToJSON(data)
}

// YAMLToJSONDecoder decodes YAML documents from an io.Reader by
// separating individual documents. It first converts the YAML
// body to JSON, then unmarshals the JSON.
Expand Down Expand Up @@ -143,11 +154,19 @@ func (d *YAMLOrJSONDecoder) Decode(into interface{}) error {
func guessJSONStream(r io.Reader, size int) (io.Reader, bool) {
buffer := bufio.NewReaderSize(r, size)
b, _ := buffer.Peek(size)
return buffer, hasPrefix(b, []byte("{"))
return buffer, hasJSONPrefix(b)
}

var jsonPrefix = []byte("{")

// hasJSONPrefix returns true if the provided buffer appears to start with
// a JSON open brace.
func hasJSONPrefix(buf []byte) bool {
return hasPrefix(buf, jsonPrefix)
}

// Return true if the first non-whitespace bytes in buf is
// prefix
// prefix.
func hasPrefix(buf []byte, prefix []byte) bool {
trim := bytes.TrimLeftFunc(buf, unicode.IsSpace)
return bytes.HasPrefix(trim, prefix)
Expand Down

0 comments on commit 71abc99

Please sign in to comment.