Moment library implements its own toJSON function returning string format: http://momentjs.com/docs/#/displaying/as-json/ As moment object has toJSON function the replacer used to stringify pyson expressions never receive a moment object because it is dumped before. It is needed to prepare pyson object as same design as Sao.rpc.prepareObject issue6027 review31701002
839 lines
29 KiB
JavaScript
839 lines
29 KiB
JavaScript
/* This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
this repository contains the full copyright notices and license terms. */
|
|
(function() {
|
|
'use strict';
|
|
|
|
Sao.PYSON = {};
|
|
Sao.PYSON.eval = {};
|
|
|
|
Sao.PYSON.PYSON = Sao.class_(Object, {
|
|
init: function() {
|
|
},
|
|
pyson: function() {
|
|
throw 'NotImplementedError';
|
|
},
|
|
types: function() {
|
|
throw 'NotImplementedError';
|
|
},
|
|
toString: function() {
|
|
var klass = this.pyson().__class__;
|
|
var args = this.__string_params__().map(function(p){
|
|
if (p instanceof Sao.PYSON.PYSON) {
|
|
return p.toString();
|
|
} else {
|
|
return JSON.stringify(p);
|
|
}
|
|
});
|
|
return klass + '(' + args.join(', ') + ')';
|
|
},
|
|
__string_params__: function() {
|
|
throw 'NotImplementedError';
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.PYSON.eval_ = function(value, context) {
|
|
throw 'NotImplementedError';
|
|
};
|
|
Sao.PYSON.PYSON.init_from_object = function(object) {
|
|
throw 'NotImplementedError';
|
|
};
|
|
|
|
Sao.PYSON.Encoder = Sao.class_(Object, {
|
|
prepare: function(value, index, parent) {
|
|
if (value !== null && value !== undefined) {
|
|
if (value instanceof Array) {
|
|
value = jQuery.extend([], value);
|
|
for (var i = 0, length = value.length; i < length; i++) {
|
|
this.prepare(value[i], i, value);
|
|
}
|
|
} else if (value._isAMomentObject) {
|
|
if (value.isDate) {
|
|
value = new Sao.PYSON.Date(
|
|
value.year(),
|
|
value.month() + 1,
|
|
value.date()).pyson();
|
|
} else {
|
|
value = new Sao.PYSON.DateTime(
|
|
value.year(),
|
|
value.month() + 1,
|
|
value.date(),
|
|
value.hours(),
|
|
value.minutes(),
|
|
value.seconds(),
|
|
value.milliseconds() * 1000).pyson();
|
|
}
|
|
}
|
|
}
|
|
if (parent) {
|
|
parent[index] = value;
|
|
}
|
|
return parent || value;
|
|
},
|
|
|
|
encode: function(pyson) {
|
|
pyson = this.prepare(pyson);
|
|
return JSON.stringify(pyson, function(k, v) {
|
|
if (v instanceof Sao.PYSON.PYSON) {
|
|
return v.pyson();
|
|
} else if (v === null || v === undefined) {
|
|
return null;
|
|
}
|
|
return v;
|
|
});
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Decoder = Sao.class_(Object, {
|
|
init: function(context, noeval) {
|
|
this.__context = context || {};
|
|
this.noeval = noeval || false;
|
|
},
|
|
decode: function(str) {
|
|
var reviver = function(k, v) {
|
|
if (typeof v == 'object' && v !== null) {
|
|
var cls = Sao.PYSON[v.__class__];
|
|
if (cls) {
|
|
if (!this.noeval) {
|
|
return cls.eval_(v, this.__context);
|
|
} else {
|
|
var args = jQuery.extend({}, v);
|
|
delete args.__class__;
|
|
return Sao.PYSON[v.__class__].init_from_object(
|
|
args);
|
|
}
|
|
}
|
|
}
|
|
return v;
|
|
};
|
|
return JSON.parse(str, reviver.bind(this));
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.eval.Eval = function(value, default_) {
|
|
return new Sao.PYSON.Eval(value, default_);
|
|
};
|
|
Sao.PYSON.Eval = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(value, default_) {
|
|
if (default_ === undefined) {
|
|
default_ = '';
|
|
}
|
|
Sao.PYSON.Eval._super.init.call(this);
|
|
this._value = value;
|
|
this._default = default_;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'Eval',
|
|
'v': this._value,
|
|
'd': this._default
|
|
};
|
|
},
|
|
types: function() {
|
|
if (this._default instanceof Sao.PYSON.PYSON) {
|
|
return this._default.types();
|
|
} else {
|
|
return [typeof this._default];
|
|
}
|
|
},
|
|
__string_params__: function() {
|
|
return [this._value, this._default];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Eval.eval_ = function(value, context) {
|
|
if (value.v in context) {
|
|
return context[value.v];
|
|
} else {
|
|
return value.d;
|
|
}
|
|
};
|
|
Sao.PYSON.Eval.init_from_object = function(obj) {
|
|
return new Sao.PYSON.Eval(obj.v, obj.d);
|
|
};
|
|
|
|
Sao.PYSON.eval.Not = function(value) {
|
|
return new Sao.PYSON.Not(value);
|
|
};
|
|
Sao.PYSON.Not = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(value) {
|
|
Sao.PYSON.Not._super.init.call(this);
|
|
if (value instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(value.types()).not(['boolean', 'object']).length ||
|
|
jQuery(['boolean']).not(value.types()).length) {
|
|
throw 'value must be boolean';
|
|
}
|
|
} else {
|
|
if (typeof value != 'boolean') {
|
|
throw 'value must be boolean';
|
|
}
|
|
}
|
|
this._value = value;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'Not',
|
|
'v': this._value
|
|
};
|
|
},
|
|
types: function() {
|
|
return ['boolean'];
|
|
},
|
|
__string_params__: function() {
|
|
return [this._value];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Not.eval_ = function(value, context) {
|
|
return !value.v;
|
|
};
|
|
Sao.PYSON.Not.init_from_object = function(obj) {
|
|
return new Sao.PYSON.Not(obj.v);
|
|
};
|
|
|
|
Sao.PYSON.eval.Bool = function(value) {
|
|
return new Sao.PYSON.Bool(value);
|
|
};
|
|
Sao.PYSON.Bool = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(value) {
|
|
Sao.PYSON.Bool._super.init.call(this);
|
|
this._value = value;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'Bool',
|
|
'v': this._value
|
|
};
|
|
},
|
|
types: function() {
|
|
return ['boolean'];
|
|
},
|
|
__string_params__: function() {
|
|
return [this._value];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Bool.eval_ = function(value, context) {
|
|
if (moment.isMoment(value.v) && value.v.isTime) {
|
|
return Boolean(value.v.hour() || value.v.minute() ||
|
|
value.v.second() || value.v.millisecond());
|
|
} else if (moment.isDuration(value.v)) {
|
|
return Boolean(value.v.valueOf());
|
|
} else if (value.v instanceof Object) {
|
|
return !jQuery.isEmptyObject(value.v);
|
|
} else {
|
|
return Boolean(value.v);
|
|
}
|
|
};
|
|
Sao.PYSON.Bool.init_from_object = function(obj) {
|
|
return new Sao.PYSON.Bool(obj.v);
|
|
};
|
|
|
|
|
|
Sao.PYSON.eval.And = function(statements) {
|
|
return new Sao.PYSON.And(statements);
|
|
};
|
|
Sao.PYSON.And = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(statements) {
|
|
if (statements === undefined) {
|
|
statements = [];
|
|
}
|
|
Sao.PYSON.And._super.init.call(this);
|
|
for (var i = 0, len = statements.length; i < len; i++) {
|
|
var statement = statements[i];
|
|
if (statement instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(statement.types()).not(['boolean']).length ||
|
|
jQuery(['boolean']).not(statement.types()).length) {
|
|
throw 'statement must be boolean';
|
|
}
|
|
} else {
|
|
if (typeof statement != 'boolean') {
|
|
throw 'statement must be boolean';
|
|
}
|
|
}
|
|
}
|
|
if (statements.length < 2) {
|
|
throw 'must have at least 2 statements';
|
|
}
|
|
this._statements = statements;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'And',
|
|
's': this._statements
|
|
};
|
|
},
|
|
types: function() {
|
|
return ['boolean'];
|
|
},
|
|
__string_params__: function() {
|
|
return this._statements;
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.And.eval_ = function(value, context) {
|
|
var result = true;
|
|
for (var i = 0, len = value.s.length; i < len; i++) {
|
|
var statement = value.s[i];
|
|
result = result && statement;
|
|
}
|
|
return result;
|
|
};
|
|
Sao.PYSON.And.init_from_object = function(obj) {
|
|
return new Sao.PYSON.And(obj.s);
|
|
};
|
|
|
|
|
|
Sao.PYSON.eval.Or = function(statements) {
|
|
return new Sao.PYSON.Or(statements);
|
|
};
|
|
Sao.PYSON.Or = Sao.class_(Sao.PYSON.And, {
|
|
pyson: function() {
|
|
var result = Sao.PYSON.Or._super.pyson.call(this);
|
|
result.__class__ = 'Or';
|
|
return result;
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Or.eval_ = function(value, context) {
|
|
var result = false;
|
|
for (var i = 0, len = value.s.length; i < len; i++) {
|
|
var statement = value.s[i];
|
|
result = result || statement;
|
|
}
|
|
return result;
|
|
};
|
|
Sao.PYSON.Or.init_from_object= function(obj) {
|
|
return new Sao.PYSON.Or(obj.s);
|
|
};
|
|
|
|
Sao.PYSON.eval.Equal = function(statement1, statement2) {
|
|
return new Sao.PYSON.Equal(statement1, statement2);
|
|
};
|
|
Sao.PYSON.Equal = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(statement1, statement2) {
|
|
Sao.PYSON.Equal._super.init.call(this);
|
|
var types1, types2;
|
|
if (statement1 instanceof Sao.PYSON.PYSON) {
|
|
types1 = statement1.types();
|
|
} else {
|
|
types1 = [typeof statement1];
|
|
}
|
|
if (statement2 instanceof Sao.PYSON.PYSON) {
|
|
types2 = statement2.types();
|
|
} else {
|
|
types2 = [typeof statement2];
|
|
}
|
|
if (jQuery(types1).not(types2).length ||
|
|
jQuery(types2).not(types1).length) {
|
|
throw 'statements must have the same type';
|
|
}
|
|
this._statement1 = statement1;
|
|
this._statement2 = statement2;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'Equal',
|
|
's1': this._statement1,
|
|
's2': this._statement2
|
|
};
|
|
},
|
|
types: function() {
|
|
return ['boolean'];
|
|
},
|
|
__string_params__: function() {
|
|
return [this._statement1, this._statement2];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Equal.eval_ = function(value, context) {
|
|
if (value.s1 instanceof Array && value.s2 instanceof Array) {
|
|
return Sao.common.compare(value.s1, value.s2);
|
|
} else {
|
|
return value.s1 == value.s2;
|
|
}
|
|
};
|
|
Sao.PYSON.Equal.init_from_object = function(obj) {
|
|
return new Sao.PYSON.Equal(obj.s1, obj.s2);
|
|
};
|
|
|
|
Sao.PYSON.eval.Greater = function(statement1, statement2, equal) {
|
|
return new Sao.PYSON.Greater(statement1, statement2, equal);
|
|
};
|
|
Sao.PYSON.Greater = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(statement1, statement2, equal) {
|
|
Sao.PYSON.Greater._super.init.call(this);
|
|
var statements = [statement1, statement2];
|
|
for (var i = 0; i < 2; i++) {
|
|
var statement = statements[i];
|
|
if (statement instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(statement).not(['number']).length) {
|
|
throw 'statement must be an integer or a float';
|
|
}
|
|
} else {
|
|
if (!~['number', 'object'].indexOf(typeof statement)) {
|
|
throw 'statement must be an integer or a float';
|
|
}
|
|
}
|
|
}
|
|
if (equal === undefined) {
|
|
equal = false;
|
|
}
|
|
if (equal instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(equal.types()).not(['boolean']).length ||
|
|
jQuery(['boolean']).not(equal.types()).length) {
|
|
throw 'equal must be boolean';
|
|
}
|
|
} else {
|
|
if (typeof equal != 'boolean') {
|
|
throw 'equal must be boolean';
|
|
}
|
|
}
|
|
this._statement1 = statement1;
|
|
this._statement2 = statement2;
|
|
this._equal = equal;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'Greater',
|
|
's1': this._statement1,
|
|
's2': this._statement2,
|
|
'e': this._equal
|
|
};
|
|
},
|
|
types: function() {
|
|
return ['boolean'];
|
|
},
|
|
__string_params__: function() {
|
|
return [this._statement1, this._statement2, this._equal];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Greater._convert = function(value) {
|
|
value = jQuery.extend({}, value);
|
|
value.s1 = Number(value.s1);
|
|
value.s2 = Number(value.s2);
|
|
return value;
|
|
};
|
|
|
|
Sao.PYSON.Greater.eval_ = function(value, context) {
|
|
value = Sao.PYSON.Greater._convert(value);
|
|
if (value.e) {
|
|
return value.s1 >= value.s2;
|
|
} else {
|
|
return value.s1 > value.s2;
|
|
}
|
|
};
|
|
Sao.PYSON.Greater.init_from_object = function(obj) {
|
|
return new Sao.PYSON.Greater(obj.s1, obj.s2, obj.e);
|
|
};
|
|
|
|
Sao.PYSON.eval.Less = function(statement1, statement2, equal) {
|
|
return new Sao.PYSON.Less(statement1, statement2, equal);
|
|
};
|
|
Sao.PYSON.Less = Sao.class_(Sao.PYSON.Greater, {
|
|
pyson: function() {
|
|
var result = Sao.PYSON.Less._super.pyson.call(this);
|
|
result.__class__ = 'Less';
|
|
return result;
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Less._convert = Sao.PYSON.Greater._convert;
|
|
|
|
Sao.PYSON.Less.eval_ = function(value, context) {
|
|
value = Sao.PYSON.Less._convert(value);
|
|
if (value.e) {
|
|
return value.s1 <= value.s2;
|
|
} else {
|
|
return value.s1 < value.s2;
|
|
}
|
|
};
|
|
Sao.PYSON.Less.init_from_object = function(obj) {
|
|
return new Sao.PYSON.Less(obj.s1, obj.s2, obj.e);
|
|
};
|
|
|
|
Sao.PYSON.eval.If = function(condition, then_statement, else_statement) {
|
|
return new Sao.PYSON.If(condition, then_statement, else_statement);
|
|
};
|
|
Sao.PYSON.If = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(condition, then_statement, else_statement) {
|
|
Sao.PYSON.If._super.init.call(this);
|
|
if (condition instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(condition.types()).not(['boolean']).length ||
|
|
jQuery(['boolean']).not(condition.types()).length) {
|
|
throw 'condition must be boolean';
|
|
}
|
|
} else {
|
|
if (typeof condition != 'boolean') {
|
|
throw 'condition must be boolean';
|
|
}
|
|
}
|
|
var then_types, else_types;
|
|
if (then_statement instanceof Sao.PYSON.PYSON) {
|
|
then_types = then_statement.types();
|
|
} else {
|
|
then_types = [typeof then_statement];
|
|
}
|
|
if (else_statement === undefined) {
|
|
else_statement = null;
|
|
}
|
|
if (else_statement instanceof Sao.PYSON.PYSON) {
|
|
else_types = else_statement.types();
|
|
} else {
|
|
else_types = [typeof else_statement];
|
|
}
|
|
if (jQuery(then_types).not(else_types).length ||
|
|
jQuery(else_types).not(then_types).length) {
|
|
throw 'then and else statements must be the same type';
|
|
}
|
|
this._condition = condition;
|
|
this._then_statement = then_statement;
|
|
this._else_statement = else_statement;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'If',
|
|
'c': this._condition,
|
|
't': this._then_statement,
|
|
'e': this._else_statement
|
|
};
|
|
},
|
|
types: function() {
|
|
if (this._then_statement instanceof Sao.PYSON.PYSON) {
|
|
return this._then_statement.types();
|
|
} else {
|
|
return [typeof this._then_statement];
|
|
}
|
|
},
|
|
__string_params__: function() {
|
|
return [this._condition, this._then_statement,
|
|
this._else_statement];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.If.eval_ = function(value, context) {
|
|
if (value.c) {
|
|
return value.t;
|
|
} else {
|
|
return value.e;
|
|
}
|
|
};
|
|
Sao.PYSON.If.init_from_object = function(obj) {
|
|
return new Sao.PYSON.If(obj.c, obj.t, obj.e);
|
|
};
|
|
|
|
Sao.PYSON.eval.Get = function(obj, key, default_) {
|
|
return new Sao.PYSON.Get(obj, key, default_);
|
|
};
|
|
Sao.PYSON.Get = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(obj, key, default_) {
|
|
Sao.PYSON.Get._super.init.call(this);
|
|
if (default_ === undefined) {
|
|
default_ = null;
|
|
}
|
|
if (obj instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(obj.types()).not(['object']).length ||
|
|
jQuery(['object']).not(obj.types()).length) {
|
|
throw 'obj must be a dict';
|
|
}
|
|
} else {
|
|
if (!(obj instanceof Object)) {
|
|
throw 'obj must be a dict';
|
|
}
|
|
}
|
|
this._obj = obj;
|
|
if (key instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(key.types()).not(['string']).length ||
|
|
jQuery(['string']).not(key.types()).length) {
|
|
throw 'key must be a string';
|
|
}
|
|
} else {
|
|
if (typeof key != 'string') {
|
|
throw 'key must be a string';
|
|
}
|
|
}
|
|
this._key = key;
|
|
this._default = default_;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'Get',
|
|
'v': this._obj,
|
|
'k': this._key,
|
|
'd': this._default
|
|
};
|
|
},
|
|
types: function() {
|
|
if (this._default instanceof Sao.PYSON.PYSON) {
|
|
return this._default.types();
|
|
} else {
|
|
return [typeof this._default];
|
|
}
|
|
},
|
|
__string_params__: function() {
|
|
return [this._obj, this._key, this._default];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Get.eval_ = function(value, context) {
|
|
if (value.k in value.v) {
|
|
return value.v[value.k];
|
|
} else {
|
|
return value.d;
|
|
}
|
|
};
|
|
Sao.PYSON.Get.init_from_object = function(obj) {
|
|
return new Sao.PYSON.Get(obj.v, obj.k, obj.d);
|
|
};
|
|
|
|
Sao.PYSON.eval.In = function(key, obj) {
|
|
return new Sao.PYSON.In(key, obj);
|
|
};
|
|
Sao.PYSON.In = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(key, obj) {
|
|
Sao.PYSON.In._super.init.call(this);
|
|
if (key instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(key.types()).not(['string', 'number']).length) {
|
|
throw 'key must be a string or a number';
|
|
}
|
|
} else {
|
|
if (!~['string', 'number'].indexOf(typeof key)) {
|
|
throw 'key must be a string or a number';
|
|
}
|
|
}
|
|
if (obj instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(obj.types()).not(['object']).length ||
|
|
jQuery(['object']).not(obj.types()).length) {
|
|
throw 'obj must be a dict or a list';
|
|
}
|
|
} else {
|
|
if (!(obj instanceof Object)) {
|
|
throw 'obj must be a dict or a list';
|
|
}
|
|
}
|
|
this._key = key;
|
|
this._obj = obj;
|
|
},
|
|
pyson: function() {
|
|
return {'__class__': 'In',
|
|
'k': this._key,
|
|
'v': this._obj
|
|
};
|
|
},
|
|
types: function() {
|
|
return ['boolean'];
|
|
},
|
|
__string_params__: function() {
|
|
return [this._key, this._obj];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.In.eval_ = function(value, context) {
|
|
if (value.v.indexOf) {
|
|
return Boolean(~value.v.indexOf(value.k));
|
|
} else {
|
|
return !!value.v[value.k];
|
|
}
|
|
};
|
|
Sao.PYSON.In.init_from_object = function(obj) {
|
|
return new Sao.PYSON.In(obj.k, obj.v);
|
|
};
|
|
|
|
Sao.PYSON.eval.Date = function(year, month, day, delta_years, delta_months,
|
|
delta_days) {
|
|
return new Sao.PYSON.Date(year, month, day, delta_years, delta_months,
|
|
delta_days);
|
|
};
|
|
Sao.PYSON.Date = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(year, month, day, delta_years, delta_months, delta_days)
|
|
{
|
|
Sao.PYSON.Date._super.init.call(this);
|
|
if (year === undefined) year = null;
|
|
if (month === undefined) month = null;
|
|
if (day === undefined) day = null;
|
|
if (delta_years === undefined) delta_years = 0;
|
|
if (delta_months === undefined) delta_months = 0;
|
|
if (delta_days === undefined) delta_days = 0;
|
|
|
|
this._test(year, 'year');
|
|
this._test(month, 'month');
|
|
this._test(day, 'day');
|
|
this._test(delta_years, 'delta_years');
|
|
this._test(delta_days, 'delta_days');
|
|
this._test(delta_months, 'delta_months');
|
|
|
|
this._year = year;
|
|
this._month = month;
|
|
this._day = day;
|
|
this._delta_years = delta_years;
|
|
this._delta_months = delta_months;
|
|
this._delta_days = delta_days;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'Date',
|
|
'y': this._year,
|
|
'M': this._month,
|
|
'd': this._day,
|
|
'dy': this._delta_years,
|
|
'dM': this._delta_months,
|
|
'dd': this._delta_days
|
|
};
|
|
},
|
|
types: function() {
|
|
return ['object'];
|
|
},
|
|
_test: function(value, name) {
|
|
if (value instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(value.types()).not(
|
|
['number', typeof null]).length) {
|
|
throw name + ' must be an integer or None';
|
|
}
|
|
} else {
|
|
if ((typeof value != 'number') && (value !== null)) {
|
|
throw name + ' must be an integer or None';
|
|
}
|
|
}
|
|
},
|
|
__string_params__: function() {
|
|
return [this._year, this._month, this._day, this._delta_years,
|
|
this._delta_months, this._delta_days];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Date.eval_ = function(value, context) {
|
|
var date = Sao.Date(value.y, value.M && value.M - 1, value.d);
|
|
if (value.dy) date.add(value.dy, 'y');
|
|
if (value.dM) date.add(value.dM, 'M');
|
|
if (value.dd) date.add(value.dd, 'd');
|
|
return date;
|
|
};
|
|
Sao.PYSON.Date.init_from_object = function(obj) {
|
|
return new Sao.PYSON.Date(obj.y, obj.M, obj.d, obj.dy, obj.dM, obj.dd);
|
|
};
|
|
|
|
Sao.PYSON.eval.DateTime = function(year, month, day, hour, minute, second,
|
|
microsecond, delta_years, delta_months, delta_days, delta_hours,
|
|
delta_minutes, delta_seconds, delta_microseconds) {
|
|
return new Sao.PYSON.DateTime(year, month, day, hour, minute, second,
|
|
microsecond, delta_years, delta_months, delta_days, delta_hours,
|
|
delta_minutes, delta_seconds, delta_microseconds);
|
|
};
|
|
Sao.PYSON.DateTime = Sao.class_(Sao.PYSON.Date, {
|
|
init: function(year, month, day, hour, minute, second, microsecond,
|
|
delta_years, delta_months, delta_days, delta_hours,
|
|
delta_minutes, delta_seconds, delta_microseconds) {
|
|
Sao.PYSON.DateTime._super.init.call(this, year, month, day,
|
|
delta_years, delta_months, delta_days);
|
|
if (hour === undefined) hour = null;
|
|
if (minute === undefined) minute = null;
|
|
if (second === undefined) second = null;
|
|
if (microsecond === undefined) microsecond = null;
|
|
if (delta_hours === undefined) delta_hours = 0;
|
|
if (delta_minutes === undefined) delta_minutes = 0;
|
|
if (delta_seconds === undefined) delta_seconds = 0;
|
|
if (delta_microseconds === undefined) delta_microseconds = 0;
|
|
|
|
this._test(hour, 'hour');
|
|
this._test(minute, 'minute');
|
|
this._test(second, 'second');
|
|
this._test(microsecond, 'microsecond');
|
|
this._test(delta_hours, 'delta_hours');
|
|
this._test(delta_minutes, 'delta_minutes');
|
|
this._test(delta_seconds, 'delta_seconds');
|
|
this._test(delta_microseconds, 'delta_microseconds');
|
|
|
|
this._hour = hour;
|
|
this._minute = minute;
|
|
this._second = second;
|
|
this._microsecond = microsecond;
|
|
this._delta_hours = delta_hours;
|
|
this._delta_minutes = delta_minutes;
|
|
this._delta_seconds = delta_seconds;
|
|
this._delta_microseconds = delta_microseconds;
|
|
},
|
|
pyson: function() {
|
|
var result = Sao.PYSON.DateTime._super.pyson.call(this);
|
|
result.__class__ = 'DateTime';
|
|
result.h = this._hour;
|
|
result.m = this._minute;
|
|
result.s = this._second;
|
|
result.ms = this._microsecond;
|
|
result.dh = this._delta_hours;
|
|
result.dm = this._delta_minutes;
|
|
result.ds = this._delta_seconds;
|
|
result.dms = this._delta_microseconds;
|
|
return result;
|
|
},
|
|
__string_params__: function() {
|
|
var date_params = Sao.PYSON.DateTime._super.__string_params__.call(
|
|
this);
|
|
return [date_params[0], date_params[1], date_params[2],
|
|
this._hour, this._minute, this._second, this._microsecond,
|
|
date_params[3], date_params[4], date_params[5],
|
|
this._delta_hours, this._delta_minutes, this._delta_seconds,
|
|
this._delta_microseconds];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.DateTime.eval_ = function(value, context) {
|
|
var date = Sao.DateTime(value.y, value.M && value.M - 1, value.d,
|
|
value.h, value.m, value.s, value.ms && value.ms / 1000);
|
|
if (value.dy) date.add(value.dy, 'y');
|
|
if (value.dM) date.add(value.dM, 'M');
|
|
if (value.dd) date.add(value.dd, 'd');
|
|
if (value.dh) date.add(value.dh, 'h');
|
|
if (value.dm) date.add(value.dm, 'm');
|
|
if (value.ds) date.add(value.ds, 's');
|
|
if (value.dms) date.add(value.dms / 1000, 'ms');
|
|
return date;
|
|
};
|
|
Sao.PYSON.DateTime.init_from_object = function(obj) {
|
|
return new Sao.PYSON.DateTime(obj.y, obj.M, obj.d, obj.h, obj.m, obj.s,
|
|
obj.ms, obj.dy, obj.dM, obj.dd, obj.dh, obj.dm, obj.ds, obj.dms);
|
|
};
|
|
|
|
Sao.PYSON.eval.Len = function(value) {
|
|
return new Sao.PYSON.Len(value);
|
|
};
|
|
Sao.PYSON.Len = Sao.class_(Sao.PYSON.PYSON, {
|
|
init: function(value) {
|
|
Sao.PYSON.Len._super.init.call(this);
|
|
if (value instanceof Sao.PYSON.PYSON) {
|
|
if (jQuery(value.types()).not(['object', 'string']).length ||
|
|
jQuery(['object', 'string']).not(value.types()).length) {
|
|
throw 'value must be an object or a string';
|
|
}
|
|
} else {
|
|
if ((typeof value != 'object') && (typeof value != 'string')) {
|
|
throw 'value must be an object or a string';
|
|
}
|
|
}
|
|
this._value = value;
|
|
},
|
|
pyson: function() {
|
|
return {
|
|
'__class__': 'Len',
|
|
'v': this._value
|
|
};
|
|
},
|
|
types: function() {
|
|
return ['integer'];
|
|
},
|
|
__string_params__: function() {
|
|
return [this._value];
|
|
}
|
|
});
|
|
|
|
Sao.PYSON.Len.eval_ = function(value, context) {
|
|
if (typeof value.v == 'object') {
|
|
return Object.keys(value.v).length;
|
|
} else {
|
|
return value.v.length;
|
|
}
|
|
};
|
|
Sao.PYSON.Len.init_from_object = function(obj) {
|
|
return new Sao.PYSON.Len(obj.v);
|
|
};
|
|
}());
|