Aleks,

On 4/11/21 12:28 PM, Aleksandar Lazic wrote:
Agree. I have now rethink how to do it and suggest to add a output type.

```
json_query(<json_path>,<output_type>)
   The <json_path> and <output_type> are mandatory.
   This converter uses the mjson library https://github.com/cesanta/mjson
   This converter extracts the value located at <json_path> from the JSON
   string in the input value.
   <json_path> must be a valid JsonPath string as defined at
   https://goessner.net/articles/JsonPath/

   These are the possible output types.
    - "bool"   : A boolean is expected;
    - "sint"   : A signed 64bits integer type is expected;
    - "str"    : A string is expected. This could be a simple string or
                 a JSON sub-object;

   A floating point value will always be converted to sint!
```

The converter should be able to detect the type on its own. The types are part of the JSON after all! The output_type argument just moves the explicit type specification from the converter name into an argument. Not much of an improvement.

I don't know how the library works exactly, but after extracting the value something like the following should work:

If the first character is '"' -> string
If the first character is 't' -> bool(true)
If the first character is 'f' -> bool(false)
If the first character is 'n' -> null (This should probably result in the converter failing).
If the first character is a digit -> number

+    { "json_string", sample_conv_json_string, ARG1(1,STR), sample_check_json_string , SMP_T_STR, SMP_USE_CONST },

While testing something I also just notice that SMP_USE_CONST is incorrect here. I cannot apply e.g. the sha1 converter to the output of json_string.

Okay. I will change both to SMP_T_ANY because the return values can be bool, int or str.

The input type should remain as SMP_T_STR, because you are parsing a JSON *string*.

While implmenting the suggested options abouve I stuggle with checking the params. Arg0 is quite clear but how make a efficient check for Arg1, the output type?

The efficiency of the check is less of a concern. That happens only once during configuration checking.


```
/* This function checks the "json_query" converter's arguments.
  */
static int sample_check_json_query(struct arg *arg, struct sample_conv *conv,
                            const char *file, int line, char **err)
{
         if (arg[0].data.str.data == 0) { /* empty */
                 memprintf(err, "json_path must not be empty");
                 return 0;
         }

                 /* this doen't work */
         int type = smp_to_type[arg[1].data.str.area];

The output_type argument should not exist. I'll answer the question nonetheless: You have to compare strings explicitly in C. So you would have use strcmp for each of the cases.

         switch (type) {
         case SMP_T_BOOL:
         case SMP_T_SINT:
             /* These type are not const. */
             break;

         case SMP_T_STR:

```

I would to the conversation from double to int like "smp->data.u.sint = (long long int ) double_val;" is this efficient. I haven't done this for a long time so I would like to have a "2nd eye pair" on this.


I'd probably return a double as a string instead. At least that doesn't destroy information.

Best regards
Tim Düsterhus

Reply via email to