Line data Source code
1 : /* 2 : This file is part of TALER 3 : (C) 2025 Taler Systems SA 4 : 5 : TALER is free software; you can redistribute it and/or modify it under the 6 : terms of the GNU Lesser General Public License as published by the Free Software 7 : Foundation; either version 3, or (at your option) any later version. 8 : 9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 : 13 : You should have received a copy of the GNU General Public License along with 14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 : */ 16 : /** 17 : * @file util/json.c 18 : * @brief helper functions to parse JSON 19 : * @author Christian Grothoff 20 : */ 21 : #include "platform.h" 22 : #include <gnunet/gnunet_common.h> 23 : #include <gnunet/gnunet_json_lib.h> 24 : #include <jansson.h> 25 : #include <taler/taler_json_lib.h> 26 : #include <taler/taler_util.h> 27 : #include "taler_merchant_util.h" 28 : 29 : 30 : /** 31 : * Parse given JSON object to `enum TALER_MERCHANT_ContractInputType` 32 : * 33 : * @param cls closure, NULL 34 : * @param root the json object representing data 35 : * @param[out] spec where to write the data 36 : * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 37 : */ 38 : static enum GNUNET_GenericReturnValue 39 15 : parse_contract_input_type (void *cls, 40 : json_t *root, 41 : struct GNUNET_JSON_Specification *spec) 42 : { 43 : static const struct Entry 44 : { 45 : const char *name; 46 : enum TALER_MERCHANT_ContractInputType val; 47 : } lt [] = { 48 : #if FUTURE 49 : { .name = "coin", 50 : .val = TALER_MERCHANT_CONTRACT_INPUT_TYPE_COIN }, 51 : #endif 52 : { .name = "token", 53 : .val = TALER_MERCHANT_CONTRACT_INPUT_TYPE_TOKEN }, 54 : { .name = NULL, 55 : .val = TALER_MERCHANT_CONTRACT_INPUT_TYPE_INVALID } 56 : }; 57 15 : enum TALER_MERCHANT_ContractInputType *res 58 : = (enum TALER_MERCHANT_ContractInputType *) spec->ptr; 59 : 60 : (void) cls; 61 15 : if (json_is_string (root)) 62 : { 63 : const char *str; 64 : 65 15 : str = json_string_value (root); 66 15 : if (NULL == str) 67 : { 68 0 : GNUNET_break_op (0); 69 0 : return GNUNET_SYSERR; 70 : } 71 15 : for (unsigned int i = 0; NULL != lt[i].name; i++) 72 : { 73 15 : if (0 == strcasecmp (str, 74 15 : lt[i].name)) 75 : { 76 15 : *res = lt[i].val; 77 15 : return GNUNET_OK; 78 : } 79 : } 80 : } 81 0 : GNUNET_break_op (0); 82 0 : return GNUNET_SYSERR; 83 : } 84 : 85 : 86 : struct GNUNET_JSON_Specification 87 15 : TALER_MERCHANT_json_spec_cit (const char *name, 88 : enum TALER_MERCHANT_ContractInputType *cit) 89 : { 90 15 : struct GNUNET_JSON_Specification ret = { 91 : .parser = &parse_contract_input_type, 92 : .field = name, 93 : .ptr = cit 94 : }; 95 : 96 15 : *cit = TALER_MERCHANT_CONTRACT_INPUT_TYPE_INVALID; 97 15 : return ret; 98 : } 99 : 100 : 101 : /** 102 : * Parse given JSON object to `enum TALER_MERCHANT_ContractOutputType` 103 : * 104 : * @param cls closure, NULL 105 : * @param root the json object representing data 106 : * @param[out] spec where to write the data 107 : * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error 108 : */ 109 : static enum GNUNET_GenericReturnValue 110 16 : parse_contract_output_type (void *cls, 111 : json_t *root, 112 : struct GNUNET_JSON_Specification *spec) 113 : { 114 : static const struct Entry 115 : { 116 : const char *name; 117 : enum TALER_MERCHANT_ContractOutputType val; 118 : } lt [] = { 119 : { .name = "token", 120 : .val = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN }, 121 : { .name = "tax-receipt", 122 : .val = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT }, 123 : #if FUTURE 124 : { .name = "coin", 125 : .val = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_COIN }, 126 : #endif 127 : { .name = NULL, 128 : .val = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID } 129 : }; 130 16 : enum TALER_MERCHANT_ContractOutputType *res 131 : = (enum TALER_MERCHANT_ContractOutputType *) spec->ptr; 132 : 133 : (void) cls; 134 16 : if (json_is_string (root)) 135 : { 136 : const char *str; 137 : 138 16 : str = json_string_value (root); 139 16 : if (NULL == str) 140 : { 141 0 : GNUNET_break_op (0); 142 0 : return GNUNET_SYSERR; 143 : } 144 17 : for (unsigned int i = 0; NULL != lt[i].name; i++) 145 : { 146 17 : if (0 == strcasecmp (str, 147 17 : lt[i].name)) 148 : { 149 16 : *res = lt[i].val; 150 16 : return GNUNET_OK; 151 : } 152 : } 153 : } 154 0 : GNUNET_break_op (0); 155 0 : return GNUNET_SYSERR; 156 : } 157 : 158 : 159 : struct GNUNET_JSON_Specification 160 16 : TALER_MERCHANT_json_spec_cot (const char *name, 161 : enum TALER_MERCHANT_ContractOutputType *cot) 162 : { 163 16 : struct GNUNET_JSON_Specification ret = { 164 : .parser = &parse_contract_output_type, 165 : .field = name, 166 : .ptr = cot 167 : }; 168 : 169 16 : *cot = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID; 170 16 : return ret; 171 : }