/// <summary> /// Processes the type and any attributes (present on the context), and adds /// intents to the context. /// </summary> /// <param name="context">The generation context.</param> public void AddConstraints(SchemaGeneratorContext context) { var attribute = context.Attributes.OfType <JsonNumberHandlingAttribute>().FirstOrDefault(); if (attribute == null) { return; } if (!context.Type.IsNumber()) { return; } var typeIntent = context.Intents.OfType <TypeIntent>().FirstOrDefault(); var existingType = typeIntent?.Type ?? default; if (attribute.Handling.HasFlag(JsonNumberHandling.AllowReadingFromString)) { context.Intents.Remove(typeIntent !); context.Intents.Add(new TypeIntent(existingType | SchemaValueType.String)); } if (attribute.Handling.HasFlag(JsonNumberHandling.AllowNamedFloatingPointLiterals)) { var currentSchema = context.Intents.ToList(); context.Intents.Clear(); context.Intents.Add(new AnyOfIntent(currentSchema, new ISchemaKeywordIntent[] { new EnumIntent("NaN", "Infinity", "-Infinity") } ) ); } }
internal void Optimize() { var thisHash = GetHashCode(); var allContexts = GetChildContexts(); var defsByHashCode = allContexts.Where(g => g.Value.Count > 1) .ToDictionary(g => g.Key, g => g.Value.Context); var currentNames = new List <string>(); var defs = new Dictionary <string, SchemaGeneratorContext>(); var contextContainers = Intents.OfType <IContextContainer>().ToList(); foreach (var def in defsByHashCode) { var name = def.Value.GetDefName(currentNames); var refIntent = new RefIntent(new Uri(def.Key == thisHash ? "#" : $"#/$defs/{name}", UriKind.Relative)); var refContext = new SchemaGeneratorContext(def.Value.Type, null); refContext.Intents.Add(refIntent); foreach (var intent in contextContainers) { intent.Replace(def.Key, refContext); } if (def.Key == thisHash) { continue; } defs[name] = def.Value; } if (defs.Any()) { var defsIntent = new DefsIntent(defs); Intents.Add(defsIntent); } }
internal static void HandleAttributes(SchemaGeneratorContext context) { var handlers = _handlers.Concat(context.Attributes.OfType <IAttributeHandler>()); foreach (var handler in handlers) { handler.AddConstraints(context); } }
void IAttributeHandler.AddConstraints(SchemaGeneratorContext context) { var attribute = context.Attributes.OfType <ReadOnlyAttribute>().FirstOrDefault(); if (attribute == null) { return; } context.Intents.Add(new ReadOnlyIntent(attribute.Value)); }
void IAttributeHandler.AddConstraints(SchemaGeneratorContext context) { var attribute = context.Attributes.OfType <DescriptionAttribute>().FirstOrDefault(); if (attribute == null) { return; } context.Intents.Add(new DescriptionIntent(attribute.Desription)); }
/// <summary> /// Generates a schema from a CLR type. /// </summary> /// <param name="builder">The schema builder.</param> /// <param name="type">The type to generate.</param> /// <returns>The schema builder (for fluent syntax support).</returns> public static JsonSchemaBuilder FromType(this JsonSchemaBuilder builder, Type type) { var context = new SchemaGeneratorContext(type, new List <Attribute>()); context.GenerateIntents(); context.Optimize(); context.Apply(builder); return(builder); }
/// <summary> /// Gets or creates a <see cref="SchemaGeneratorContext"/> based on the given /// type and attribute set. /// </summary> /// <param name="type">The type to generate.</param> /// <param name="attributes">The attribute set on the property.</param> /// <returns> /// A generation context, from the cache if one exists with the specified /// type and attribute set; otherwise a new one. New contexts are automatically /// cached. /// </returns> /// <remarks> /// Use this in your generator if it needs to create keywords with subschemas. /// </remarks> public static SchemaGeneratorContext Get(Type type, List <Attribute> attributes) { var hash = attributes?.GetAttributeSetHashCode() ?? 0; var key = new Key(type, hash); if (!Cache.TryGetValue(key, out var context)) { context = new SchemaGeneratorContext(type, attributes); _cache[key] = context; context.GenerateIntents(); } return(context); }
void IAttributeHandler.AddConstraints(SchemaGeneratorContext context) { var attribute = context.Attributes.OfType <MaxItemsAttribute>().FirstOrDefault(); if (attribute == null) { return; } if (!context.Type.IsArray()) { return; } context.Intents.Add(new MaxItemsIntent(attribute.Value)); }
void IAttributeHandler.AddConstraints(SchemaGeneratorContext context) { var attribute = context.Attributes.OfType <ExclusiveMinimumAttribute>().FirstOrDefault(); if (attribute == null) { return; } if (!context.Type.IsNumber()) { return; } context.Intents.Add(new ExclusiveMinimumIntent(attribute.Value)); }
void IAttributeHandler.AddConstraints(SchemaGeneratorContext context) { var attribute = context.Attributes.OfType <MinLengthAttribute>().FirstOrDefault(); if (attribute == null) { return; } if (context.Type != typeof(string)) { return; } context.Intents.Add(new MinLengthIntent(attribute.Length)); }
public ContextCount(SchemaGeneratorContext context) { Context = context; Count = 1; }