(local nick-pattern "^[-_a-zA-Z0-9]+$")
(local channel-pattern (nick-pattern:gsub "%^" "^#"))
(local max-length 16)
(fn nick? [state nick]
(if (or (= nil nick) (= "" nick)) (values nil :431 ":No nick given")
(state:connected? nick) (values nil :433 ":Nick in use")
(< max-length (length nick))
(values nil :432 (.. ":Nick too long, must be under " max-length))
(not (nick:match nick-pattern))
(values nil :432 ":Nick contains invalid characters")
true))
(fn user? [_state user]
(if (or (= "" user) (= nil user)) (values nil :461 ":No user provided")
(< 100 (length user)) (values nil :461 ":User name too long")
true))
(fn pass? [state pass]
(if (or (= pass state.password) (= nil state.password)) true
(values nil :464 ":Password mismatch")))
(fn channel? [_state channel-name]
(if (not (channel-name:match channel-pattern))
(values nil :403 ":Invalid channel name")
(< max-length (length channel-name))
(values nil :403 ":Channel name too long")
true))
(fn set* [state cstate field value]
(let [valid? (match field :nick nick? :user user? :pass pass?)]
(match (valid? state value)
true (doto cstate (tset field value))
(_ cmd msg) (do (state.log :invalid cmd msg)
(state:send cstate cmd msg)))))
{:set set* : nick? : user? : pass? : channel?}