/// <summary>
 /// Initializes a new instance of the <see cref="SchemaBuilder" /> class configured with
 /// the default list of cases.
 /// </summary>
 /// <param name="memberVisibility">
 /// The binding flags the builder should use to select fields and properties.
 /// </param>
 /// <param name="enumBehavior">
 /// Whether the builder should build enum schemas or integral schemas for enum types.
 /// </param>
 /// <param name="nullableReferenceTypeBehavior">
 /// The behavior the builder should apply when determining nullability of reference types.
 /// </param>
 /// <param name="temporalBehavior">
 /// Whether the builder should build string schemas (ISO 8601) or long schemas (timestamp
 /// logical types) for timestamp types.
 /// </param>
 public SchemaBuilder(
     BindingFlags memberVisibility = BindingFlags.Public | BindingFlags.Instance,
     EnumBehavior enumBehavior     = EnumBehavior.Symbolic,
     NullableReferenceTypeBehavior nullableReferenceTypeBehavior = NullableReferenceTypeBehavior.Annotated,
     TemporalBehavior temporalBehavior = TemporalBehavior.Iso8601)
     : this(CreateDefaultCaseBuilders(memberVisibility, enumBehavior, nullableReferenceTypeBehavior, temporalBehavior))
 {
 }
        /// <summary>
        /// Creates the default list of case builders.
        /// </summary>
        /// <param name="memberVisibility">
        /// The binding flags to use to select fields and properties.
        /// </param>
        /// <param name="enumBehavior">
        /// The behavior to apply when building schemas for enum types.
        /// </param>
        /// <param name="nullableReferenceTypeBehavior">
        /// The behavior to apply when determining nullability of reference types.
        /// </param>
        /// <param name="temporalBehavior">
        /// The behavior to apply when building schemas for temporal types.
        /// </param>
        /// <returns>
        /// A list of case builders that matches most .NET <see cref="Type" />s.
        /// </returns>
        public static IEnumerable <Func <ISchemaBuilder, ISchemaBuilderCase> > CreateDefaultCaseBuilders(
            BindingFlags memberVisibility = BindingFlags.Public | BindingFlags.Instance,
            EnumBehavior enumBehavior     = EnumBehavior.Symbolic,
            NullableReferenceTypeBehavior nullableReferenceTypeBehavior = NullableReferenceTypeBehavior.None,
            TemporalBehavior temporalBehavior = TemporalBehavior.Iso8601)
        {
            return(new Func <ISchemaBuilder, ISchemaBuilderCase>[]
            {
                // nullables:
                builder => new UnionSchemaBuilderCase(builder),

                // primitives:
                builder => new BooleanSchemaBuilderCase(),
                builder => new BytesSchemaBuilderCase(nullableReferenceTypeBehavior),
                builder => new DecimalSchemaBuilderCase(),
                builder => new DoubleSchemaBuilderCase(),
                builder => new FloatSchemaBuilderCase(),
                builder => new IntSchemaBuilderCase(),
                builder => new LongSchemaBuilderCase(),
                builder => new StringSchemaBuilderCase(nullableReferenceTypeBehavior),

                // enums:
                builder => new EnumSchemaBuilderCase(enumBehavior, builder),

                // dictionaries:
                builder => new MapSchemaBuilderCase(nullableReferenceTypeBehavior, builder),

                // enumerables:
                builder => new ArraySchemaBuilderCase(nullableReferenceTypeBehavior, builder),

                // built-ins:
                builder => new DurationSchemaBuilderCase(),
                builder => new TimestampSchemaBuilderCase(temporalBehavior),
                builder => new UriSchemaBuilderCase(),
                builder => new UuidSchemaBuilderCase(),

                // classes and structs:
                builder => new RecordSchemaBuilderCase(memberVisibility, nullableReferenceTypeBehavior, builder),
            });
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="EnumSchemaBuilderCase" /> class.
 /// </summary>
 /// <param name="enumBehavior">
 /// A value value indicating whether the case should build enum schemas or integral schemas.
 /// </param>
 /// <param name="schemaBuilder">
 /// A schema builder instance that will be used to build schemas for underlying integral
 /// types.
 /// </param>
 public EnumSchemaBuilderCase(EnumBehavior enumBehavior, ISchemaBuilder schemaBuilder)
 {
     EnumBehavior  = enumBehavior;
     SchemaBuilder = schemaBuilder ?? throw new ArgumentNullException(nameof(SchemaBuilder), "Schema builder cannot be null.");
 }