From 8260721d13f1012cbfd2d3ec6182c2bba6867347 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 8 Dec 2022 10:11:30 -0500 Subject: [PATCH] Add better documentation about how custom values are represented in JSON. (#23965) --- .../commands/clusters/ClusterCommand.h | 41 ++++++++++++++++-- .../commands/clusters/WriteAttributeCommand.h | 42 +++++++++++++++---- 2 files changed, 72 insertions(+), 11 deletions(-) diff --git a/examples/chip-tool/commands/clusters/ClusterCommand.h b/examples/chip-tool/commands/clusters/ClusterCommand.h index 4b8325074a8716..33320760dd9d9a 100644 --- a/examples/chip-tool/commands/clusters/ClusterCommand.h +++ b/examples/chip-tool/commands/clusters/ClusterCommand.h @@ -30,16 +30,14 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub InteractionModelCommands(this), ModelCommand("command-by-id", credsIssuerConfig) { AddArgument("cluster-id", 0, UINT32_MAX, &mClusterId); - AddArgument("command-id", 0, UINT32_MAX, &mCommandId); - AddArgument("payload", &mPayload); + AddByIdArguments(); AddArguments(); } ClusterCommand(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) : InteractionModelCommands(this), ModelCommand("command-by-id", credsIssuerConfig), mClusterId(clusterId) { - AddArgument("command-id", 0, UINT32_MAX, &mCommandId); - AddArgument("payload", &mPayload); + AddByIdArguments(); AddArguments(); } @@ -137,6 +135,41 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub // Subclasses are responsible for calling AddArguments. } + void AddByIdArguments() + { + AddArgument("command-id", 0, UINT32_MAX, &mCommandId); + AddArgument("payload", &mPayload, + "The command payload. This should be a JSON-encoded object, with string representations of field ids as keys. " + " The values for the keys are represented as follows, depending on the type:\n" + " * struct: a JSON-encoded object, with field ids as keys.\n" + " * list: a JSON-encoded array of values.\n" + " * null: A literal null.\n" + " * boolean: A literal true or false.\n" + " * unsigned integer: One of:\n" + " a) The number directly, as decimal.\n" + " b) A string starting with \"u:\" followed by decimal digits\n" + " * signed integer: One of:\n" + " a) The number directly, if it's negative.\n" + " b) A string starting with \"s:\" followed by decimal digits\n" + " * single-precision float: A string starting with \"f:\" followed by the number.\n" + " * double-precision float: One of:\n" + " a) The number directly, if it's not an integer.\n" + " b) A string starting with \"d:\" followed by the number.\n" + " * octet string: A string starting with \"hex:\" followed by the hex encoding of the bytes.\n" + " * string: A string with the characters.\n" + "\n" + " An example payload may look like this: '{ \"0x0\": { \"0\": null, \"1\": false }, \"1\": [17, \"u:17\"], " + "\"0x2\": [ -17, \"s:17\", \"s:-17\" ], \"0x3\": \"f:2\", \"0x4\": [ \"d:3\", 4.5 ], \"0x5\": \"hex:ab12\", " + "\"0x6\": \"ab12\" }' and represents:\n" + " Field 0: a struct with two fields, one with value null and one with value false.\n" + " Field 1: A list of unsigned integers.\n" + " Field 2: A list of signed integers.\n" + " Field 3: A single-precision float.\n" + " Field 4: A list of double-precision floats.\n" + " Field 5: A 2-byte octet string.\n" + " Field 6: A 4-char character string."); + } + void AddArguments() { AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs, diff --git a/examples/chip-tool/commands/clusters/WriteAttributeCommand.h b/examples/chip-tool/commands/clusters/WriteAttributeCommand.h index ac9f6233a65ff4..d220468d622260 100644 --- a/examples/chip-tool/commands/clusters/WriteAttributeCommand.h +++ b/examples/chip-tool/commands/clusters/WriteAttributeCommand.h @@ -179,22 +179,50 @@ class WriteAttribute : public InteractionModelWriter, public ModelCommand, publi AddArgument("attribute-name", attributeName, "The attribute name to write."); } - template - void AddArgumentAttributeValues(minType minValue, maxType maxValue) + template >::value, int> = 0> + static const char * GetAttributeValuesDescription() { - AddArgument("attribute-values", minValue, maxValue, &mAttributeValues, - "Comma-separated list of attribute values to write."); + return "Comma-separated list of attribute values to write. Each value is represented as follows, depending on the type:\n" + " * struct: a JSON-encoded object, with field ids as keys.\n" + " * list: a JSON-encoded array of values.\n" + " * null: A literal null.\n" + " * boolean: A literal true or false.\n" + " * unsigned integer: One of:\n" + " a) The number directly, as decimal.\n" + " b) The number directly, as 0x followed by hex digits. (Only for the toplevel value, not inside structs or " + "lists.)\n" + " c) A string starting with \"u:\" followed by decimal digits\n" + " * signed integer: One of:\n" + " a) The number directly, if it's negative.\n" + " c) A string starting with \"s:\" followed by decimal digits\n" + " * single-precision float: A string starting with \"f:\" followed by the number.\n" + " * double-precision float: One of:\n" + " a) The number directly, if it's not an integer.\n" + " b) A string starting with \"d:\" followed by the number.\n" + " * octet string: A string starting with \"hex:\" followed by the hex encoding of the bytes.\n" + " * string: A string with the characters."; } - void AddArgumentAttributeValues() + static const char * GetTypedAttributeValuesDescription() { return "Comma-separated list of attribute values to write."; } + + template >::value, int> = 0> + static const char * GetAttributeValuesDescription() { - AddArgument("attribute-values", &mAttributeValues, "Comma-separated list of attribute values to write."); + return GetTypedAttributeValuesDescription(); } + template + void AddArgumentAttributeValues(minType minValue, maxType maxValue) + { + AddArgument("attribute-values", minValue, maxValue, &mAttributeValues, GetTypedAttributeValuesDescription()); + } + + void AddArgumentAttributeValues() { AddArgument("attribute-values", &mAttributeValues, GetAttributeValuesDescription()); } + void AddArgumentAttributeValues(TypedComplexArgument & attributeParser) { attributeParser.SetArgument(&mAttributeValues); - AddArgument("attribute-values", &attributeParser, "Comma-separated list of attribute values to write."); + AddArgument("attribute-values", &attributeParser, GetTypedAttributeValuesDescription()); } void AddArguments()