uci-berry-utils/object.be

252 lines
6.4 KiB
Plaintext

# uci
import file
# native
import string
import json
# really a a nested map designe to work like a javascript object with . notation
class Object
var _obj
var _autosave # will save object(map) whenever changes are made, default: false
var _autoload # if true will attempt to load from file on init, default: true
var _status
var file # attached file instance
var _deep # depth to follow nested maps, default = -1 which mean walk until no more
# forbidden key names
# any key starting with _
# init
# member
# setmember
# assign
# retrieve
# load
# save
# get
# set
# file
# filename
# exporti
# importi
# for passing only opts must set obj to {} or nil, e.g. (nil,{'autosave':true})
def init(obj,filename,opts)
if (type(obj) == 'string')
if debug[3] print('no object passed a filename was passed') end
opts = filename
filename = obj
obj = nil
end
if isinstance(filename, map)
opts = filename
filename = nil
end
if ! opts opts = {} end
self.assign(self._isMap(obj,true)) # will set to empty map if obj is nil
if filename
if debug[3] print('filename passsed, adding file instance', filename) end
self.file = file(filename,opts.find('ext')) # create file instance
end
self._autosave = opts.find('autosave') == nil ? false : opts.find('autosave')
self._autoload = opts.find('autoload') == nil ? true : opts.find('autoload')
if self.file
if self._isMap(obj)
if self._autosave
if debug[3] print('autosaving passed object map to', self.file.name()) end
self.save()
end
else
if self._autoload
if debug[3] print('autoloading', self.file.name()) end
return self.load()
end
end
end
end
#
def load (filename)
if self.file
if debug[3] print ('loading before', self._obj) end
var obj = self.file.load(filename)
if isinstance(obj,map)
self._obj = obj
return obj
# walk object looking for additional maps?
else
if debug[3] print ('Warning: Unable to load file or file does not contain a map') end
end
if debug[3] print ('loading after',self._obj) end
end
return nil
end
def save (filename)
if self.file
if debug[3]
print ('saving', self.file.addext(filename))
print ('object to be saved', self._obj)
# print ('contents of current file', self.load(filename))
end
self.file.save(self._obj,filename)
# if debug[3] print ('after saving',self.load(filename)) end
end
end
def _isMap (m,init)
if isinstance(m, map)
return m
else
if init
return {}
else
return nil
end
end
end
def merge(m,overwrite)
for k: m.keys()
if overwrite
self._obj.setitem(k,m[k])
else
self._obj.insert(k,m[k])
end
end
return self._obj
end
def assign(obj)
if ! obj obj={} end
if isinstance(obj, map)
self._obj=obj
else
end
return self._obj
end
def retrieve()
return self._obj
end
def exporti(save)
var obj = self._obj
if save && self.file
self.save()
obj = nil
end
return { 'filename': self.filename(), 'obj':obj, 'opts':{'autosave':self._autosave, 'autoload':self._autoload} }
end
def importi(s)
print ('setting to import',s)
return Object(s.item('obj'),s.item('filename'),s.item('opts'))
end
def filename()
if self.file
return self.file.name()
else
return nil
end
end
def del(keys)
self.set(keys,'__remove__')
end
# # sets a nested property
def set(keys,value)
def _set(keys,value,obj)
if !obj obj = self._obj end
var key = keys.pop()
if !obj.find(key)
obj[key] = {}
end
if keys.size()
return _set(keys,value,obj[key])
else
if value == '__remove__'
obj.remove(key)
else
obj[key]=value
end
return true
end
end
if type(keys) == 'string' keys = string.split(keys,".") end
if !isinstance(keys,list)
print('ERROR: list of keys not passed', keys)
return nil
end
keys.reverse()
if debug[3] print('setting',keys,'to',value) end
if _set(keys,value)
if self.file && self._autosave self.save() end
end
end
def dump(subkey)
if subkey == nil return json.dump(self.get()) end
return json.dump(self.get(subkey))
end
# gets a nested property
def get(keys)
if keys == nil return self._obj end
def _get(keys,obj)
if !obj
obj = self._obj
end
var key = keys.pop()
var _obj = obj.find(key)
if debug[1]
print('current key:', key, 'remaining keys:', keys )
print('current nested object: ',_obj)
end
if isinstance(_obj,map)
if keys.size()
return _get(keys,_obj)
else
return _obj
end
else
return _obj
end
end
if type(keys) == 'string' keys = string.split(keys,".") end
if !isinstance(keys,list)
print('ERROR: list of keys not passed', keys)
return nil
end
keys.reverse()
if debug[3] print('getting',keys) end
return _get(keys)
end
# - virtual member getter, if a key does not exists return `nil`-#
def member(key)
return self._obj.find(key)
end
#- virtual member setter -#
def setmember(key, value)
if debug[3]
print ('setting key=>', key,':', value)
end
self._obj[key] = value
if self._autosave self.save() end
return self.member(key)
end
end # Object Class
var object = module('object')
object = Object
return object