読者です 読者をやめる 読者になる 読者になる

素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: すかいぷ:javascripter_  か javascripter あっと tsukkun.net skypeのほうがいいです

JSONの検証

javascript
var JMatch = {
  type : {
    string: function (value) {
      return typeof value == "string";
    },
    number: function (value) {
      return typeof value == "number";
    },
    boolean: function (value) {
      return typeof value == "boolean";
    },
    object: function (value) {
      // XXX: JMatch.type.object([]) == false?
      return value instanceof Object;
    },
    array: function (value) {
      return value instanceof Array;
    },
    nil: function (value) {
      return value == null;
    },
    any: function  (value, exists) {
      return exists;
    },
    size: function (type, minimum, maximum) {
      if (typeof minimum == "undefined")
        minimum = -Infinity;
      if (typeof maximum == "undefined")
        maximum = Infinity;
      var inRange;
      switch (type) {
      case "number": case "integer":
        inRange = function (value) {
          return minimum < value && value < maximum;
        };
        break;
      case "string": case "array":
        inRange = function (value) {
          return minumum < value.length && value.length < maximum;
        };
        break;
      default:
        throw new TypeError("Unknown type: " + type);
      }
      return function (value) {
        return JMatch.type[type](value) && inRange(value);
      };
    },
  },
  optional: function (type){
    return function (value, exists) {
      return exists? type(value): true;
    };
  },
  test: function (instance, schema, _exists) {
    if (typeof _exists == "undefined")
      _exists = true;
    if (typeof schema == "function")
      return schema(instance, _exists);
    function check(p) {
      return !this.test(instance[p], schema[p], p in instance);
    }
    if (this.type.array(instance) && this.type.array(schema)) {
      for (var i = 0; i < instance.length; i++)
        if (check.call(this, i))
          return false;
      for (var i = instance.length; i < schema.length; i++)
        if (check.call(this, i))
          return false;
      return true;
    }
    if (this.type.object(instance) && this.type.object(schema)) {
      var keys = [];
      for (var k in schema) {
        keys.push(k);
        if (check.call(this, k))
          return false;
      }
      for (var k in instance)
        if (keys.indexOf(k) < 0)
          return false;
      return true;
    }
    return instance == schema;
  }
};

JMatch.test({
  user: "foobar",
  id: 12345,
  premium: false
}, {
  user: JMatch.type.string,
  id: JMatch.type.size("number", 0, 99999),
  premium: JMatch.type.boolean,
});