You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2019/11/13 20:57:09 UTC
[mynewt-newtmgr] 02/02: res: Add `--int` option to parse numbers as
ints
This is an automated email from the ASF dual-hosted git repository.
ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newtmgr.git
commit 67028755ca66fcebad05826c462e54c84248ad3a
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Mon Nov 11 09:37:15 2019 -0800
res: Add `--int` option to parse numbers as ints
JSON only supports a single numeric type: "number". When the `res -j`
command parses a payload, the JSON unmarshal function parses all numbers
as instances of float64. This makes the resulting CBOR payload
incorrect when the user just wants to use integers.
This commit adds an option to the res command: `--int`. When specified,
all numbers in the payload are converted to integers when the conversion
does not result in a change in value. For example, `1.0` is converted
to an integer, but `1.5` is not.
---
newtmgr/cli/res.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/newtmgr/cli/res.go b/newtmgr/cli/res.go
index 9fd6aee..2dce1b0 100644
--- a/newtmgr/cli/res.go
+++ b/newtmgr/cli/res.go
@@ -38,6 +38,7 @@ import (
var details bool
var resJson bool
+var resInt bool
func indent(s string, numSpaces int) string {
b := make([]byte, numSpaces)
@@ -190,6 +191,46 @@ func parsePayloadMap(args []string) (map[string]interface{}, error) {
return m, nil
}
+// removeFloats processes an unmarshalled JSON value, converting float64 values
+// to int64 values where possible. For arrays, it is recursively called on
+// each element. For objects (maps), it is recursively called on each value.
+// A float is converted to an int if conversion does not result in a change in
+// value. For example, `2.0` is converted, but `1.5` is not.
+func removeFloats(itf interface{}) interface{} {
+ tryToInt64 := func(f float64) interface{} {
+ i := int64(f)
+ if float64(i) == f {
+ return i
+ } else {
+ return f
+ }
+ }
+
+ switch actual := itf.(type) {
+ case float32:
+ return tryToInt64(float64(actual))
+
+ case float64:
+ return tryToInt64(actual)
+
+ case []interface{}:
+ for i, val := range actual {
+ actual[i] = removeFloats(val)
+ }
+ return actual
+
+ case map[string]interface{}:
+ for k, v := range actual {
+ actual[k] = removeFloats(v)
+ }
+
+ return actual
+
+ default:
+ return actual
+ }
+}
+
func parsePayloadJson(args []string) (interface{}, error) {
if len(args) == 0 {
return nil, nil
@@ -201,6 +242,12 @@ func parsePayloadJson(args []string) (interface{}, error) {
return nil, util.ChildNewtError(err)
}
+ // If the user specified `--int`, convert floats to ints where it does not
+ // result in truncation.
+ if resInt {
+ val = removeFloats(val)
+ }
+
return val, nil
}
@@ -291,6 +338,9 @@ func resCmd() *cobra.Command {
"Show more details about the CoAP response")
resCmd.PersistentFlags().BoolVarP(&resJson, "json", "j", false,
"Accept a JSON string for the CoAP message body (not `k=v` pairs)")
+ resCmd.PersistentFlags().BoolVarP(&resInt, "int", "", false,
+ "Parse all numbers as integer values where possible "+
+ "(only applicable when combined with -j)")
return resCmd
}