/// <summary> /// Serves as a hash function for a particular type. /// </summary> /// <returns> /// A hash code for the current <see cref="T:System.Object"/>. /// </returns> public override int GetHashCode() { unchecked { var hashCode = Type.GetHashCode(); hashCode = (hashCode * 397) ^ (Id?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Schema?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Title?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Description?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Default?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ MultipleOf.GetHashCode(); hashCode = (hashCode * 397) ^ Maximum.GetHashCode(); hashCode = (hashCode * 397) ^ ExclusiveMaximum.GetHashCode(); hashCode = (hashCode * 397) ^ Minimum.GetHashCode(); hashCode = (hashCode * 397) ^ ExclusiveMinimum.GetHashCode(); hashCode = (hashCode * 397) ^ (MaxLength?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (MinLength?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Pattern?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (AdditionalItems?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Items?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (MaxItems?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (MinItems?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (UniqueItems?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Contains?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (AdditionalProperties?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Definitions?.GetCollectionHashCode().GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Properties?.GetCollectionHashCode() ?? 0); hashCode = (hashCode * 397) ^ (PatternProperties?.GetCollectionHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Dependencies?.GetCollectionHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Const?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Enum?.GetCollectionHashCode() ?? 0); hashCode = (hashCode * 397) ^ (AllOf?.GetCollectionHashCode() ?? 0); hashCode = (hashCode * 397) ^ (AnyOf?.GetCollectionHashCode() ?? 0); hashCode = (hashCode * 397) ^ (OneOf?.GetCollectionHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Not?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Format?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Required?.GetCollectionHashCode() ?? 0); hashCode = (hashCode * 397) ^ (Examples?.GetCollectionHashCode() ?? 0); return(hashCode); } }
/// <summary> /// Converts an object to a <see cref="JsonValue"/>. /// </summary> /// <param name="serializer">The <see cref="JsonSerializer"/> instance to use for additional serialization of values.</param> /// <returns>The <see cref="JsonValue"/> representation of the object.</returns> public virtual JsonValue ToJson(JsonSerializer serializer) { var json = new JsonObject(); if (Id != null) { json["id"] = Id; } if (!string.IsNullOrWhiteSpace(Schema)) { json["$schema"] = Schema; } if (Title != null) { json["title"] = Title; } if (!string.IsNullOrWhiteSpace(Description)) { json["description"] = Description; } if (Default != null) { json["default"] = Default; } if (MultipleOf.HasValue) { json["multipleOf"] = MultipleOf; } if (Maximum.HasValue) { json["maximum"] = Maximum; } if (ExclusiveMaximum.HasValue) { json["exclusiveMaximum"] = ExclusiveMaximum; } if (Minimum.HasValue) { json["minimum"] = Minimum; } if (ExclusiveMinimum.HasValue) { json["exclusiveMinimum"] = ExclusiveMinimum; } if (MaxLength.HasValue) { json["maxLength"] = MaxLength; } if (MinLength.HasValue) { json["minLength"] = MinLength; } if (Pattern != null) { json["pattern"] = Pattern; } if (AdditionalItems != null) { json["additionalItems"] = AdditionalItems.ToJson(serializer); } if (Items != null) { json["items"] = Items.ToJson(serializer); } if (MaxItems.HasValue) { json["maxItems"] = MinItems; } if (MinItems.HasValue) { json["minItems"] = MinItems; } if (UniqueItems ?? false) { json["uniqueItems"] = UniqueItems; } if (MaxProperties.HasValue) { json["maxProperties"] = MaxProperties; } if (MinProperties.HasValue) { json["minProperties"] = MinProperties; } if (Required != null) { var array = Required.ToJson(); array.Array.EqualityStandard = ArrayEquality.ContentsEqual; json["required"] = array; } if (AdditionalProperties != null) { json["additionalProperties"] = AdditionalProperties.ToJson(serializer); } if (Definitions != null) { json["definitions"] = Definitions.ToJson(serializer); } if (Properties != null) { json["properties"] = Properties.ToJson(serializer); } if (PatternProperties != null && PatternProperties.Any()) { json["patternProperties"] = PatternProperties.ToDictionary(kvp => kvp.Key.ToString(), kvp => kvp.Value).ToJson(serializer); } if (Dependencies != null && Dependencies.Any()) { var jsonDependencies = new JsonObject(); foreach (var dependency in Dependencies) { jsonDependencies[dependency.PropertyName] = dependency.GetJsonData(); } json["dependencies"] = jsonDependencies; } if (Enum != null) { var array = Enum.ToJson(serializer); array.Array.EqualityStandard = ArrayEquality.ContentsEqual; json["enum"] = Enum.ToJson(serializer); } if (Type != JsonSchemaType.NotDefined) { var array = Type.ToJson(); if (array.Type == JsonValueType.Array) { array.Array.EqualityStandard = ArrayEquality.ContentsEqual; } json["type"] = array; } if (AllOf != null) { var array = AllOf.Select(s => s.ToJson(serializer)).ToJson(); array.EqualityStandard = ArrayEquality.ContentsEqual; json["allOf"] = array; } if (AnyOf != null) { var array = AnyOf.Select(s => s.ToJson(serializer)).ToJson(); array.EqualityStandard = ArrayEquality.ContentsEqual; json["anyOf"] = array; } if (OneOf != null) { var array = OneOf.Select(s => s.ToJson(serializer)).ToJson(); array.EqualityStandard = ArrayEquality.ContentsEqual; json["oneOf"] = array; } if (Not != null) { json["not"] = Not.ToJson(serializer); } if (Format != null) { json["format"] = Format.Key; } if (ExtraneousDetails != null) { foreach (var kvp in ExtraneousDetails.Where(kvp => !_definedProperties.Contains(kvp.Key))) { json[kvp.Key] = kvp.Value; } } return(json); }
/// <summary> /// Builds an object from a <see cref="JsonValue"/>. /// </summary> /// <param name="json">The <see cref="JsonValue"/> representation of the object.</param> /// <param name="serializer">The <see cref="JsonSerializer"/> instance to use for additional serialization of values.</param> public virtual void FromJson(JsonValue json, JsonSerializer serializer) { var obj = json.Object; Id = obj.TryGetString("id"); var uriFolder = DocumentPath?.OriginalString.EndsWith("/") ?? true ? DocumentPath : DocumentPath?.GetParentUri(); if (!string.IsNullOrWhiteSpace(Id) && (Uri.TryCreate(Id, UriKind.Absolute, out Uri uri) || Uri.TryCreate(uriFolder + Id, UriKind.Absolute, out uri))) { DocumentPath = uri; JsonSchemaRegistry.Register(this); } Schema = obj.TryGetString("$schema"); Title = obj.TryGetString("title"); Description = obj.TryGetString("description"); if (obj.ContainsKey("default")) { Default = obj["default"]; } MultipleOf = obj.TryGetNumber("multipleOf"); Maximum = obj.TryGetNumber("maximum"); ExclusiveMaximum = obj.TryGetBoolean("exclusiveMaximum"); Minimum = obj.TryGetNumber("minimum"); ExclusiveMinimum = obj.TryGetBoolean("exclusiveMinimum"); MaxLength = (uint?)obj.TryGetNumber("maxLength"); MinLength = (uint?)obj.TryGetNumber("minLength"); Pattern = obj.TryGetString("pattern"); if (obj.ContainsKey("additionalItems")) { if (obj["additionalItems"].Type == JsonValueType.Boolean) { AdditionalItems = obj["additionalItems"].Boolean ? AdditionalItems.True : AdditionalItems.False; } else { AdditionalItems = new AdditionalItems { Definition = _ReadSchema(obj["additionalItems"]) } }; } MaxItems = (uint?)obj.TryGetNumber("maxItems"); MinItems = (uint?)obj.TryGetNumber("minItems"); if (obj.ContainsKey("items")) { Items = JsonSchemaFactory.FromJson(obj["items"], DocumentPath); } UniqueItems = obj.TryGetBoolean("uniqueItems"); MaxProperties = (uint?)obj.TryGetNumber("maxProperties"); MinProperties = (uint?)obj.TryGetNumber("minProperties"); if (obj.ContainsKey("properties")) { Properties = obj["properties"].Object.ToDictionary(kvp => kvp.Key, kvp => _ReadSchema(kvp.Value)); } Required = obj.TryGetArray("required")?.Select(jv => jv.String).ToList(); if (obj.ContainsKey("additionalProperties")) { if (obj["additionalProperties"].Type == JsonValueType.Boolean) { AdditionalProperties = obj["additionalProperties"].Boolean ? AdditionalProperties.True : AdditionalProperties.False; } else { AdditionalProperties = new AdditionalProperties { Definition = _ReadSchema(obj["additionalProperties"]) } }; } if (obj.ContainsKey("definitions")) { Definitions = obj["definitions"].Object.ToDictionary(kvp => kvp.Key, kvp => _ReadSchema(kvp.Value)); } if (obj.ContainsKey("patternProperties")) { var patterns = obj["patternProperties"].Object; PatternProperties = patterns.ToDictionary(kvp => new Regex(kvp.Key), kvp => _ReadSchema(kvp.Value)); } if (obj.ContainsKey("dependencies")) { Dependencies = obj["dependencies"].Object.Select(v => { IJsonSchemaDependency dependency; switch (v.Value.Type) { case JsonValueType.Object: dependency = new SchemaDependency(v.Key, _ReadSchema(v.Value)); break; case JsonValueType.Array: if (!v.Value.Array.Any()) { throw new ArgumentException("Property dependency must declare at least one property."); } dependency = new PropertyDependency(v.Key, v.Value.Array.Select(jv => jv.String)); break; default: throw new ArgumentOutOfRangeException(); } return(dependency); }); } if (obj.ContainsKey("enum")) { Enum = json.Object["enum"].Array.Select(jv => new EnumSchemaValue(jv)); } if (obj.ContainsKey("type")) { Type = obj["type"].FromJson(); } if (obj.ContainsKey("allOf")) { AllOf = obj["allOf"].Array.Select(_ReadSchema); } if (obj.ContainsKey("anyOf")) { AnyOf = json.Object["anyOf"].Array.Select(_ReadSchema); } if (obj.ContainsKey("oneOf")) { OneOf = obj["oneOf"].Array.Select(_ReadSchema); } if (obj.ContainsKey("not")) { Not = _ReadSchema(obj["not"]); } var formatKey = obj.TryGetString("format"); Format = StringFormat.GetFormat(formatKey); var details = obj.Where(kvp => !_definedProperties.Contains(kvp.Key)).ToJson(); if (details.Any()) { ExtraneousDetails = details; } }