1 |
Class("Joose.TypeConstraint", { |
2 |
has: { |
3 |
_constraints: { |
4 |
is: "ro", |
5 |
init: function () { return [] } |
6 |
}, |
7 |
_coercions: { |
8 |
is: "ro", |
9 |
init: function () { return [] } |
10 |
}, |
11 |
_messages: { |
12 |
is: "ro", |
13 |
init: function () { return [] } |
14 |
}, |
15 |
_name: { |
16 |
is: "ro" |
17 |
} |
18 |
}, |
19 |
|
20 |
classMethods: { |
21 |
newFromTypeBuilder: function (name, props) { |
22 |
var t |
23 |
if(props.isa) { |
24 |
t = props.isa.makeSubType(name); |
25 |
} else { |
26 |
t = new Joose.TypeConstraint({ name: name }); |
27 |
} |
28 |
|
29 |
if(props.where) { |
30 |
t.addConstraint(props.where) |
31 |
} |
32 |
|
33 |
if(props.coerce) { |
34 |
for(var i = 0; i < props.coerce.length; i++) { |
35 |
var coercionProps = props.coerce[i]; |
36 |
t.addCoercion(new Joose.TypeCoercion({ |
37 |
from: coercionProps.from, |
38 |
via: coercionProps.via |
39 |
})) |
40 |
} |
41 |
} |
42 |
|
43 |
return t |
44 |
} |
45 |
}, |
46 |
|
47 |
methods: { |
48 |
|
49 |
stringify: function () { |
50 |
return this._name |
51 |
}, |
52 |
|
53 |
makeSubType: function (name) { |
54 |
var t = new Joose.TypeConstraint({ name: name }) |
55 |
Joose.A.each(this._constraints, function (con) { |
56 |
t.addConstraint(con) |
57 |
}) |
58 |
return t |
59 |
}, |
60 |
|
61 |
addCoercion: function (coercion) { |
62 |
this._coercions.push(coercion); |
63 |
}, |
64 |
|
65 |
addConstraint: function (func, message) { |
66 |
this._constraints.push(func); |
67 |
this._messages.push(message) |
68 |
}, |
69 |
|
70 |
validateBool: function (value) { |
71 |
var i = this._validate(value); |
72 |
if(i == -1) { |
73 |
return true |
74 |
} |
75 |
return false |
76 |
}, |
77 |
|
78 |
validate: function (value) { |
79 |
var i = this._validate(value); |
80 |
if(i == -1) { |
81 |
return true |
82 |
} |
83 |
var message = this._messages[i]; |
84 |
if(message) { |
85 |
throw new ReferenceError(message.apply(this, value)) |
86 |
} |
87 |
throw new ReferenceError("The passed value ["+value+"] is not a "+this) |
88 |
}, |
89 |
|
90 |
_validate: function (value) { |
91 |
var con = this._constraints; |
92 |
var i; |
93 |
for(i = 0, len = con.length; i < len; i++) { |
94 |
var func = con[i]; |
95 |
var result = false; |
96 |
if(func instanceof RegExp) { |
97 |
result = func.test(value) |
98 |
} else { |
99 |
result = func.call(this, value) |
100 |
} |
101 |
|
102 |
if(!result) { |
103 |
return i |
104 |
|
105 |
} |
106 |
} |
107 |
return -1 |
108 |
}, |
109 |
coerce: function (value) { |
110 |
if(this.validateBool(value)) { |
111 |
return value |
112 |
} |
113 |
var coercions = this._coercions; |
114 |
for(var i = 0, len = coercions.length; i < len; i++) { |
115 |
var coercion = coercions[i]; |
116 |
var result = coercion.coerce(value); |
117 |
if(result != null) { |
118 |
return result |
119 |
} |
120 |
} |
121 |
return null |
122 |
} |
123 |
} |
124 |
}) |