lib/vobject/vcard/v3_0/paramcheck.rb
require "rsec"
require "set"
require "uri"
require "date"
include Rsec::Helpers
require "vobject"
module Vcard::V3_0
class Paramcheck
class << self
def paramcheck(strict, prop, params, ctx)
errors = []
if params && params[:TYPE]
parse_err(strict, errors, "multiple values for :TYPE parameter of #{prop}", ctx) if params[:TYPE].is_a?(Array) && params[:TYPE].length > 1 && prop != :EMAIL && prop != :ADR && prop != :TEL && prop != :LABEL && prop != :IMPP
end
case prop
when :NAME, :PROFILE, :GEO, :PRODID, :URL, :VERSION, :CLASS
parse_err(strict, errors, "illegal parameters #{params} given for #{prop}", ctx) unless params.empty?
when :CALURI, :CAPURI, :CALADRURI, :FBURL
params.each do |key, val|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless key == :TYPE
if params[:TYPE].is_a?(Array)
val.each do |v|
parse_err(strict, errors, "illegal parameter value #{v} given for parameter #{key} of #{prop}", ctx) unless v == "PREF"
end
else
parse_err(strict, errors, "illegal parameter value #{val} given for parameter #{key} of #{prop}", ctx) unless val == "PREF"
end
end
when :SOURCE
params.each do |key, val|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless key == :VALUE || key == :CONTEXT || key =~ /^x/i
parse_err(strict, errors, "illegal value #{val} given for parameter #{key} of #{prop}", ctx) if key == :VALUE && val != "uri"
parse_err(strict, errors, "illegal value #{val} given for parameter #{key} of #{prop}", ctx) if key == :CONTEXT && val != "word"
end
when :FN, :N, :NICKNAME, :MAILER, :TITLE, :ROLE, :ORG, :CATEGORIES, :NOTE, :SORT_STRING
params.each do |key, val|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless key == :VALUE || key == :LANGUAGE || key =~ /^x/i
parse_err(strict, errors, "illegal value #{val} given for parameter #{key} of #{prop}", ctx) if key == :VALUE && val != "ptext"
end
when :TEL, :IMPP, :UID
# UID included here per errata
params.each_key do |key|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless key == :TYPE
end
# we do not check the values of the :TEL :TYPE parameter, because they include ianaToken
when :EMAIL
params.each_key do |key|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless key == :TYPE
end
# we do not check the values of the first :EMAIL :TYPE parameter, because they include ianaToken
when :ADR, :LABEL
params.each do |key, val|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless [:VALUE, :LANGUAGE, :TYPE].include? key || key =~ /^x/i
parse_err(strict, errors, "illegal value #{val} given for parameter #{key} of #{prop}", ctx) if key == :VALUE && val != "ptext"
end
# we do not check the values of the :ADR :TYPE parameter, because they include ianaToken
when :KEY
params.each do |key, val|
# VALUE included here per errata
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless [:TYPE, :ENCODING, :VALUE].include? key
parse_err(strict, errors, "illegal value #{val} given for parameter #{key} of #{prop}", ctx) if key == :VALUE && val != "binary"
end
# we do not check the values of the :KEY :TYPE parameter, because they include ianaToken
when :PHOTO, :LOGO, :SOUND
params.each_key do |key|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless [:VALUE, :TYPE, :ENCODING].include? key
end
parse_err(strict, errors, "illegal value #{params[:VALUE]} of :VALUE given for #{prop}", ctx) if params[:VALUE] && params[:VALUE] != "binary" && params[:VALUE] != "uri"
parse_err(strict, errors, "illegal value #{params[:ENCODING]} of :ENCODING given for #{prop}", ctx) if params[:ENCODING] && (params[:ENCODING] != "b" || params[:VALUE] == "uri")
parse_err(strict, errors, "mandatory parameter of :ENCODING missing for #{prop}", ctx) if !params.has_key?(:ENCODING) && (!params.key?(:VALUE) || params[:VALUE] == "binary")
# TODO restriction of :TYPE to image types registered with IANA
# TODO restriction of :TYPE to sound types registered with IANA
when :BDAY, :REV
params.each_key do |key|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless key == :VALUE
end
parse_err(strict, errors, "illegal value #{params[:VALUE]} of :VALUE given for #{prop}", ctx) if params[:VALUE] && params[:VALUE] != "date" && params[:VALUE] != "date-time"
when :AGENT
params.each_key do |key|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless key == :VALUE
end
parse_err(strict, errors, "illegal value #{params[:VALUE]} of :VALUE given for #{prop}", ctx) if params[:VALUE] && params[:VALUE] != "uri"
when :TZ
# example in definition contradicts spec! Spec says :TZ takes no params at all
params.each_key do |key|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless key == :VALUE
end
parse_err(strict, errors, "illegal value #{params[:VALUE]} of :VALUE given for #{prop}", ctx) if params[:VALUE] && params[:VALUE] != "text"
else
params.each_key do |key|
parse_err(strict, errors, "illegal parameter #{key} given for #{prop}", ctx) unless key == :VALUE || key == :LANGUAGE || key =~ /^x/i
parse_err(strict, errors, "illegal value #{val} given for parameter #{key} of #{prop}") if key == :VALUE && val != "ptext"
end
end
errors
end
private
def parse_err(strict, errors, msg, ctx)
if strict
raise ctx.report_error msg, "source"
else
errors << ctx.report_error(msg, "source")
end
end
end
end
end