Пример #1
0
        /// <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") }
                                                    )
                                    );
            }
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        internal static void HandleAttributes(SchemaGeneratorContext context)
        {
            var handlers = _handlers.Concat(context.Attributes.OfType <IAttributeHandler>());

            foreach (var handler in handlers)
            {
                handler.AddConstraints(context);
            }
        }
Пример #4
0
        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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        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));
        }
Пример #9
0
        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));
        }
Пример #10
0
        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));
        }
Пример #11
0
 public ContextCount(SchemaGeneratorContext context)
 {
     Context = context;
     Count   = 1;
 }