+function core.pos_to_string(pos, decimal_places)
+ local x = pos.x
+ local y = pos.y
+ local z = pos.z
+ if decimal_places ~= nil then
+ x = string.format("%." .. decimal_places .. "f", x)
+ y = string.format("%." .. decimal_places .. "f", y)
+ z = string.format("%." .. decimal_places .. "f", z)
+ end
+ return "(" .. x .. "," .. y .. "," .. z .. ")"
+end
+
+--------------------------------------------------------------------------------
+function core.string_to_pos(value)
+ if value == nil then
+ return nil
+ end
+
+ local p = {}
+ p.x, p.y, p.z = string.match(value, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
+ if p.x and p.y and p.z then
+ p.x = tonumber(p.x)
+ p.y = tonumber(p.y)
+ p.z = tonumber(p.z)
+ return p
+ end
+ local p = {}
+ p.x, p.y, p.z = string.match(value, "^%( *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) *%)$")
+ if p.x and p.y and p.z then
+ p.x = tonumber(p.x)
+ p.y = tonumber(p.y)
+ p.z = tonumber(p.z)
+ return p
+ end
+ return nil
+end
+
+assert(core.string_to_pos("10.0, 5, -2").x == 10)
+assert(core.string_to_pos("( 10.0, 5, -2)").z == -2)
+assert(core.string_to_pos("asd, 5, -2)") == nil)
+
+--------------------------------------------------------------------------------
+function core.string_to_area(value)
+ local p1, p2 = unpack(value:split(") ("))
+ if p1 == nil or p2 == nil then
+ return nil
+ end
+
+ p1 = core.string_to_pos(p1 .. ")")
+ p2 = core.string_to_pos("(" .. p2)
+ if p1 == nil or p2 == nil then
+ return nil
+ end
+
+ return p1, p2
+end
+
+local function test_string_to_area()
+ local p1, p2 = core.string_to_area("(10.0, 5, -2) ( 30.2, 4, -12.53)")
+ assert(p1.x == 10.0 and p1.y == 5 and p1.z == -2)
+ assert(p2.x == 30.2 and p2.y == 4 and p2.z == -12.53)
+
+ p1, p2 = core.string_to_area("(10.0, 5, -2 30.2, 4, -12.53")
+ assert(p1 == nil and p2 == nil)
+
+ p1, p2 = core.string_to_area("(10.0, 5,) -2 fgdf2, 4, -12.53")
+ assert(p1 == nil and p2 == nil)