lualiteral
lualiteral
function lualiteral( value [, alias] ) --> str
Description
It creates a string containig a string representation of the argument. The string will contain a valid Lua literal, so the same limitation of the Lua parser holds:
-
Only nil, boolean, number, string or table value are allowed, no userdata or lightuserdata
-
The table must no contain any cycle
-
The table have a limited nested level size (200)
The case of table with two (or more) contents pointing to the same camera can not be written as Lua literal. However this function will support such cases generating two (or more) different tables with the same content. Cycles are still not supported.
Optionally this function let you to substitute all the references to a particular table with a supplied string. In this way also circular table may somehow handled.
Parameters
- value
-
The Lua value you want to serialize as Lua literal.
- alias
-
A table containig a map from other table to strings. When serializing the value, each sub-table will be subtituded by the string in the alias table (if any).
Return Values
- str
-
The string containig a Lua literal representing the value passed as argument.
Code
--ZFUNC-lualiteral-v0 local function lualiteral( value, alias ) --> str --TODO -- export ??? local function atomdump( val ) local t = type( val ) if "nil" == t then return 'nil' elseif "number" == t then return tostring( val ) elseif "boolean" == t then return tostring( val ) elseif "string" ~= t then val = tostring( val ) end return string.format( "%q", val ) end local function lualiteral_rec( cur, alias, result ) if "table" ~= type( cur ) then table.insert( result, atomdump( cur ) ) else -- If a table alias is defined, use that name local substitute if alias then substitute = alias[ cur ] end if substitute then table.insert( result, substitute ) else -- Recurse over each key and each value table.insert( result, "{" ) for k, v in pairs( cur ) do table.insert( result, "[" ) lualiteral_rec( k, alias, result ) table.insert( result, "]=" ) lualiteral_rec( v, alias, result ) table.insert( result, "," ) end table.insert( result, "}" ) end end return result end local result = lualiteral_rec( value, alias, {} ) return table.concat( result ) end return lualiteral
Examples
local t = require "taptest" local lualiteral = require "lualiteral" -- Plain types t( lualiteral( nil ), "nil" ) t( lualiteral( true ), "true" ) t( lualiteral( 1 ), "1" ) t( lualiteral( "ok" ), '"ok"' ) -- Table type t( lualiteral( {} ), "{}" ) t( lualiteral( { false } ), "{[1]=false,}" ) t( lualiteral( { a = true } ), '{["a"]=true,}' ) t( lualiteral( { b = 'hi' } ), '{["b"]="hi",}' ) t( lualiteral( { c = 1 } ), '{["c"]=1,}' ) t( lualiteral( { d = {} } ), '{["d"]={},}' ) -- String quoting local astr = '"\n\r\0' t( lualiteral( astr ), string.format( "%q", astr ) ) -- Sub-table t( lualiteral( { e = { f = true } } ), '{["e"]={["f"]=true,},}' ) -- Table key t( lualiteral( { [ { k = "k" } ] = true } ), '{[{["k"]="k",}]=true,}' ) -- Same tables are exapande local atab = { t = "t" } t( lualiteral( { atab, atab } ), '{[1]={["t"]="t",},[2]={["t"]="t",},}' ) -- Table alias support local alias = {} alias[ atab ] = "X" t( lualiteral( { atab, atab }, alias ), '{[1]=X,[2]=X,}' ) -- Mix example atab = { a = "a", b = { "c", "d", { e = "f" } }, [ { [ "g" ] = true } ] = { [true] = "h", }, ["i"] = atab, } local recon = lualiteral( atab, alias ) local function patterncheck(a, b) return (nil ~= a:match(b)) end t( recon, '%["a"%]="a",', patterncheck ) t( recon, '%["b"%]={%[1%]="c",%[2%]="d",%[3%]={%["e"%]="f",},},', patterncheck ) t( recon, '%[{%["g"%]=true,}%]={%[true%]="h",},', patterncheck ) t( recon, '%["i"%]=X,', patterncheck ) t()