summaryrefslogtreecommitdiffstats
path: root/acf/model/init.lua
diff options
context:
space:
mode:
authorKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-03-20 12:11:52 +0200
committerKaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>2013-03-25 12:48:07 +0200
commit0c7832085ca024f848c1fb4074d8783c1226dfde (patch)
tree6f71ae56daa97a044819b6650f97ce5e8144748b /acf/model/init.lua
parentb14a24ff75864f0d4a6eed10effd3276df5147bd (diff)
downloadaconf-0c7832085ca024f848c1fb4074d8783c1226dfde.tar.bz2
aconf-0c7832085ca024f848c1fb4074d8783c1226dfde.tar.xz
refactor the way context is passed to Field and Collection objects
Diffstat (limited to 'acf/model/init.lua')
-rw-r--r--acf/model/init.lua103
1 files changed, 52 insertions, 51 deletions
diff --git a/acf/model/init.lua b/acf/model/init.lua
index 44b1f5e..6b1fd64 100644
--- a/acf/model/init.lua
+++ b/acf/model/init.lua
@@ -36,9 +36,9 @@ require 'stringy'
local Primitive = class(Field)
-function Primitive:validate(txn, path, value)
+function Primitive:validate(context, value)
local t = self.dtype
- if type(value) ~= t then raise(path, 'Not a '..t) end
+ if type(value) ~= t then raise(context.path, 'Not a '..t) end
end
@@ -49,15 +49,15 @@ function String:init(params)
self.dtype = 'string'
end
-function String:validate(txn, path, value)
- super(self, String):validate(txn, path, value)
+function String:validate(context, value)
+ super(self, String):validate(context, value)
if self['max-length'] and string.len(value) > self['max-length'] then
- raise(path, 'Maximum length exceeded')
+ raise(context.path, 'Maximum length exceeded')
end
end
-function String:meta(txn, path, addr)
- local res = super(self, String):meta(txn, path, addr)
+function String:meta(context)
+ local res = super(self, String):meta(context)
res['max-length'] = self['max-length']
return res
end
@@ -70,10 +70,9 @@ function Number:init(params)
self.dtype = 'number'
end
-function Number:_validate(txn, path, value)
+function Number:_validate(context, value)
return super(self, Number):_validate(
- txn,
- path,
+ context,
value and tonumber(value) or value
)
end
@@ -81,9 +80,9 @@ end
Integer = class(Number)
-function Integer:validate(txn, path, value)
- super(self, Integer):validate(txn, path, value)
- if math.floor(value) ~= value then raise(path, 'Not an integer') end
+function Integer:validate(context, value)
+ super(self, Integer):validate(context, value)
+ if math.floor(value) ~= value then raise(context.path, 'Not an integer') end
end
@@ -103,12 +102,10 @@ function Range:init(params)
if not self.type then self.type = Integer end
end
-function Range:validate(txn, path, value)
+function Range:validate(context, value)
local comps = stringy.split(value, '-')
- if #comps > 2 then raise(path, 'Invalid range') end
- for _, v in ipairs(comps) do
- to_field(self.type):_validate(txn, path, v)
- end
+ if #comps > 2 then raise(context.path, 'Invalid range') end
+ for _, v in ipairs(comps) do to_field(self.type):_validate(context, v) end
end
@@ -120,16 +117,17 @@ function Reference:init(params)
if not self.scope then self.scope = '/' end
end
-function Reference:abs_scope(path)
- return pth.to_absolute(self.scope, pth.parent(path))
+function Reference:abs_scope(context)
+ return pth.to_absolute(self.scope, node.path(context.parent))
end
-function Reference:meta(txn, path, addr)
- local res = super(self, Reference):meta(txn, path, addr)
- res.scope = self:abs_scope(path)
+function Reference:meta(context)
+ local res = super(self, Reference):meta(context)
+ res.scope = self:abs_scope(context)
+ local txn = context.txn
local objs = txn:get(
- getmetatable(relabel('system', txn.search, txn, res.scope)).addr
+ node.addr(relabel('system', txn.search, txn, res.scope))
) or {}
res.choice = map(function(p) return pth.join(res.scope, p) end, objs)
res['ui-choice'] = objs
@@ -137,25 +135,26 @@ function Reference:meta(txn, path, addr)
return res
end
-function Reference:follow(txn, path, value)
- return txn:search(pth.join(self:abs_scope(path), value))
+function Reference:follow(context, value)
+ return context.txn:search(pth.join(self:abs_scope(context), value))
end
-function Reference:load(txn, path, addr)
- local ref = super(self, Reference):load(txn, path, addr)
- return ref and self:follow(txn, path, ref) or nil
+function Reference:load(context)
+ local ref = super(self, Reference):load(context)
+ return ref and self:follow(context, ref) or nil
end
-function Reference:_validate(txn, path, value)
- super(self, Reference):_validate(txn, path, value)
+function Reference:_validate(context, value)
+ super(self, Reference):_validate(context, value)
if value == nil then return end
- if object.isinstance(value, node.TreeNode) then
- value = getmetatable(value).path
- end
- if value and pth.is_absolute(value) then
- local scope = self:abs_scope(path)
+ if object.isinstance(value, node.TreeNode) then value = node.path(value) end
+
+ local path = context.path
+
+ if pth.is_absolute(value) then
+ local scope = self:abs_scope(context)
local prefix = scope..'/'
if not stringy.startswith(value, prefix) then
raise(path, 'Reference out of scope ('..scope..')')
@@ -169,7 +168,7 @@ function Reference:_validate(txn, path, value)
end
-- TODO check instance type
- relabel(path, self.follow, self, txn, path, value)
+ relabel(path, self.follow, self, context, value)
return value
end
@@ -188,9 +187,12 @@ function Collection:init(params, ctype)
self.widget = self.dtype
end
-function Collection:load(txn, path, addr)
+function Collection:load(context)
-- automatically create missing collection (TODO: make this configurable?)
- return self.ctype(txn, path, addr, to_field(self.type), self.required)
+ return self.ctype(
+ context,
+ {field=to_field(self.type), required=self.required}
+ )
end
@@ -208,30 +210,29 @@ function Mixed:init()
super(self, Mixed):init({type=Mixed}, node.Mixed)
end
-function Mixed:load(txn, path, addr)
- local value = Primitive.load(self, txn, path, addr)
- if type(value) == 'table' then
- return super(self, Mixed):load(txn, path, addr)
- end
+function Mixed:load(context)
+ local value = Primitive.load(self, context)
+ if type(value) == 'table' then return super(self, Mixed):load(context) end
return value
end
-function Mixed:save(txn, path, addr, value)
- if type(value) == 'table' then
- super(self, Mixed):save(txn, path, addr, value)
- else Primitive.save(self, txn, path, addr, value) end
+function Mixed:save(context, value)
+ if type(value) == 'table' then super(self, Mixed):save(context, value)
+ else Primitive.save(self, context, value) end
end
RootModel = new()
-function RootModel:init(txn) super(self, RootModel):init(txn, '/') end
+function RootModel:init(txn) super(self, RootModel):init{txn=txn, path='/'} end
function register(name, path, field)
local field = to_field(field)
- function field:compute(txn, pth, addr)
- return self:load(txn, '/'..name, path)
+ function field:compute(context)
+ context.path = '/'..name
+ context.addr = path
+ return self:load(context)
end
RootModel[name] = field
end