From 744828a4debc375492e9c538a748cdf9ca7a120a Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Wed, 22 Jul 2020 18:32:23 +0100 Subject: [PATCH] rc: allow JSON parameters to simplify command line usage If the parameter being passed is an object then it can be passed as a JSON string rather than using the `--json` flag which simplifies the command line. rclone rc operations/list fs=/tmp remote=test opt='{"showHash": true}' Rather than rclone rc operations/list --json '{"fs": "/tmp", "remote": "test", "opt": {"showHash": true}}' --- docs/content/rc.md | 18 ++++++++++++++++++ fs/rc/params.go | 7 +++++++ fs/rc/params_test.go | 14 ++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/docs/content/rc.md b/docs/content/rc.md index 4caae1b37..ee9f08fa2 100644 --- a/docs/content/rc.md +++ b/docs/content/rc.md @@ -165,6 +165,8 @@ $ rclone rc rc/noop param1=one param2=two Run `rclone rc` on its own to see the help for the installed remote control commands. +## JSON input + `rclone rc` also supports a `--json` flag which can be used to send more complicated input parameters. @@ -184,6 +186,22 @@ $ rclone rc --json '{ "p1": [1,"2",null,4], "p2": { "a":1, "b":2 } }' rc/noop } ``` +If the parameter being passed is an object then it can be passed as a +JSON string rather than using the `--json` flag which simplifies the +command line. + +``` +rclone rc operations/list fs=/tmp remote=test opt='{"showHash": true}' +``` + +Rather than + +``` +rclone rc operations/list --json '{"fs": "/tmp", "remote": "test", "opt": {"showHash": true}}' +``` + + + ## Special parameters The rc interface supports some special parameters which apply to diff --git a/fs/rc/params.go b/fs/rc/params.go index dd0d57317..ae7f932e5 100644 --- a/fs/rc/params.go +++ b/fs/rc/params.go @@ -219,6 +219,13 @@ func (p Params) GetStruct(key string, out interface{}) error { } err = Reshape(out, value) if err != nil { + if valueStr, ok := value.(string); ok { + // try to unmarshal as JSON if string + err = json.Unmarshal([]byte(valueStr), out) + if err == nil { + return nil + } + } return ErrParamInvalid{errors.Wrapf(err, "key %q", key)} } return nil diff --git a/fs/rc/params_test.go b/fs/rc/params_test.go index 27529f70b..1ceeee430 100644 --- a/fs/rc/params_test.go +++ b/fs/rc/params_test.go @@ -304,6 +304,20 @@ func TestParamsGetStruct(t *testing.T) { assert.Equal(t, true, IsErrParamInvalid(e3), e3.Error()) } +func TestParamsGetStructString(t *testing.T) { + in := Params{ + "struct": `{"String": "one", "Float": 4.2}`, + } + var out struct { + String string + Float float64 + } + e1 := in.GetStruct("struct", &out) + assert.NoError(t, e1) + assert.Equal(t, "one", out.String) + assert.Equal(t, 4.2, out.Float) +} + func TestParamsGetStructMissingOK(t *testing.T) { in := Params{ "struct": Params{