Composing JSON in CMake (a small set of macros to make it easier...)

So I was working with string(JSON…SET…) to compose a JSON string and after a while it became increasingly hard to understand just what I had written… especially semicolon separated lists… my brain looks at them as lists not node/field addresses within a JSON string.

After a while I came up with the following… hopefully self explanatory…

node/field addresses are simple separated by “/” instead of a “;”

Code:

macro(JSONSetField thedocument fieldname fieldtype value)

	# change / to ; so fieldname expands properly
	#
	STRING(REGEX REPLACE "/" ";" properfieldname "${fieldname}")

	if("${fieldtype}" STREQUAL "object")
		string(JSON ${thedocument} SET "${${thedocument}}" ${properfieldname} "{}")
	elseif("${fieldtype}" STREQUAL "array")
		string(JSON ${thedocument} SET "${${thedocument}}" ${properfieldname} "[]")
	elseif("${fieldtype}" STREQUAL "string")
		string(JSON ${thedocument} SET "${${thedocument}}" ${properfieldname} "\"${value}\"")
	elseif("${fieldtype}" STREQUAL "number")
		string(JSON ${thedocument} SET "${${thedocument}}" ${properfieldname} ${value})
	elseif("${fieldtype}" STREQUAL "bool")
		if(value)
			string(JSON ${thedocument} SET "${${thedocument}}"	${properfieldname} "true")
		else()
			string(JSON ${thedocument} SET "${${thedocument}}"	${properfieldname} "false")
		endif()
	endif()
endmacro()


macro(JSONCreateDocument thedocument)
	set(${thedocument} "{}")
endmacro()

macro(JSONCreateFieldObject thedocument fieldname)
	JSONSetField(${thedocument} ${fieldname} object "")
endmacro()

macro(JSONCreateFieldArray thedocument fieldname)
	JSONSetField(${thedocument} ${fieldname} array "")
endmacro()

Usage:

JSONCreateDocument(mydocument)
	JSONSetField(mydocument "varA" string "hello")
	JSONSetField(mydocument "varB" string "goodbye")

	JSONCreateFieldObject(mydocument "varC")
		JSONSetField(mydocument "varC/varD" string "hello inside varC object")
		JSONSetField(mydocument "varC/varE" string "goodbye inside varC object")
		JSONSetField(mydocument "varC/varF" number 1000)
		JSONSetField(mydocument "varC/varG" bool true)

		JSONCreateFieldObject(mydocument "varC/varH")
			JSONSetField(mydocument "varC/varH/varI" string "hello really inside")
			JSONSetField(mydocument "varC/varH/varJ" string "goodbye really inside")
			JSONSetField(mydocument "varC/varH/varK" number 2000)
			JSONSetField(mydocument "varC/varH/varL" bool false)

	JSONCreateFieldArray(mydocument "varM")
		JSONSetField(mydocument "varM/0" string "hellofromindex[0]")
		JSONCreateFieldObject(mydocument "varM/1")
			JSONSetField(mydocument "varM/1/varN" string "inarray[1]inobjectinfield")
			JSONCreateFieldObject(mydocument "varM/2")
			JSONSetField(mydocument "varM/2/varN" string "inarray[2]inobjectinfield")

MESSAGE(STATUS ">>>>> ${mydocument} <<<<<")

which produces…

-- >>>>> {
  "varA" : "hello",
  "varB" : "goodbye",
  "varC" :
  {
    "varD" : "hello inside varC object",
    "varE" : "goodbye inside varC object",
    "varF" : 1000,
    "varG" : false,
    "varH" :
    {
      "varI" : "hello really inside",
      "varJ" : "goodbye really inside",
      "varK" : 2000,
      "varL" : false
    }
  },
  "varM" :
  [
    "hellofromindex[0]",
    {
      "varN" : "inarray[1]inobjectinfield"
    },
    {
      "varN" : "inarray[2]inobjectinfield"
    }
  ]
} <<<<<

I hope this is useful in some way…

cheers