lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Aapo Talvensaari once stated:
> On 16 June 2015 at 23:51, Aapo Talvensaari <aapo.talvensaari@gmail.com>
> wrote:
> >
> > > I'm quite happy with lua-resty-validation but a few things needs to be
> > resolved still. E.g. those that I mentioned in my previous post in this
> > thread.
> >
> 
> Those problems were:
> 
> 1. How should I implement "optional" filters (and what to do with them,
> skip or continue with next, or should this be parameterized somehow)
> 2. How should I implement "stop" filters (aka those that skip rest of the
> chain)
> 3. How should I implement "default" values (do I need to have this by
> filters or by filter chain or both)
> 4. Should I split validation (e.g. true/false checks) and filters (those
> that modify values) – righth now my implementation supports validators,
> filters and validating filters (but this might look too much magic).
> 5. How should I handle absent values (missing values and nils don't
> neccessarely mean that something is wrong with input, see below).
> 
> 
> And also a few other probems:
> 
> 6. Allow validation / filtering on some other value only happen if some
> other GET/POST values is something.
> 7. Check that two fields contain same value
> 8. If one check box is checked the value of other field should be say
> between 1 and 10 and if not checked it can be between 1 and 100, for
> example.
> 9. Support multivalued fields (e.g. ?foo=1&foo=apple&foo=foo)
> 
> I can do this just fine right now:
> local ok, err = validation.tonumber().between(1, 100).outside(40, 50)(
> cgi.get['foo'])
> 
> And of course this can be reused:
> local is_some_important_number = validation.tonumber().between(1,
> 100).outside(40, 50)
> local ok, err = is_some_important_number(cgi.get['foo'])
> 
> But it is pretty hard to combine all the functionality (e.g. those
> mentioned above) neatly in these kind of oneliners. But I'm quite close, it
> just needs some rethinking (maybe I need to split some functionality or
> just use a few if clauses on more difficult input data).

  Crazy wild time.  Using Lua 5.3 and taking a page from LPeg:

	v = require "validate"

	ex4 = v.value'foo' / function(c) return c:upper() end
	foo = ex4:match(cgi.get)

	is_some_import_number = v.tonumber'foo' 
			& v.between(1,100)
			& ~v.between(40,50)

	num,err = is_some_important_number(cgi.get)

	checked = v.match('CHECKED',true) | v.default(false)
	if checked:match(cgi.post['transform') then ... end

	ex7 = v.value'one' == v.value'two'
	if ex7:match(cgi.post) then ... end

	ex8 =  v.checked'narrow' & v.tonumber'range' & v.between(1,10)
	    |                      v.tonumber'range' & v.between(1,100)

	-- or you could be more explict:
	--     v.checked'narrow' & v.tonumber'range' & v.between(1,10)
        --  | ~v.checked'narrow' & v.tonumber'range' & v.between(1,100)

	if ex8:match(cgi.post) then ... end

	ex9 = v.multiple('foo')
	list = ex9:match(cgi.post)

  Also, let's extend example 4 a bit:

	ex4 = (v.value'foo' / function(c) return c:upper() end) -- get cgi.post.foo and convert to upper case
	    & ('foo' == "HELLO" | 'foo' == "GOODBYE")           -- return if it's "HELLO" or "GOODBYE"
	    | "DEFAULT VALUE"                                   -- otherwise, return some precanned value

	salutation = ex4:match(cgi.get)

  If you need Lua 5.1/5.2 support, then you could follow LPeg even more and
use '*' (for and), '+' (for or) and - (for not).

  The example code may not be consistent with itself---it's just throwing
out an idea about how to compose filters and validation.

  -spc