Repository: danielgtaylor/huma
Pull request #515 (2024-07-19 15:26:48)

fix(schema): proper minimum, maximum in generated schemas.
It's similar to #512, but about `minimum` and `maximum`

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit


- **New Features**
	- Enhanced validation for minimum and maximum fields in schema generation, ensuring accurate representation of constraints.
	- Introduced a new type, `TypedIntegerWithCustomLimits`, allowing for specific integer limits in schemas.

- **Bug Fixes**
	- Improved robustness of schema generation by preventing errors when required tags are absent.

- **Tests**
	- Expanded test coverage for schema transformations, validating various scenarios for the new integer limit type.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Patch:
diff --git a/schema.go b/schema.go
index f96d34c..4f664b7 100644
--- a/schema.go
+++ b/schema.go
@@ -550,9 +550,15 @@ func SchemaFromField(registry Registry, f reflect.StructField, hint string) *Sch
 		}
 	}
 
-	fs.Minimum = floatTag(f, "minimum")
+	if _, ok := f.Tag.Lookup("minimum"); ok {
+		fs.Minimum = floatTag(f, "minimum")
+	}
+
 	fs.ExclusiveMinimum = floatTag(f, "exclusiveMinimum")
-	fs.Maximum = floatTag(f, "maximum")
+
+	if _, ok := f.Tag.Lookup("maximum"); ok {
+		fs.Maximum = floatTag(f, "maximum")
+	}
 	fs.ExclusiveMaximum = floatTag(f, "exclusiveMaximum")
 	fs.MultipleOf = floatTag(f, "multipleOf")
 	if _, ok := f.Tag.Lookup("minLength"); ok {


Test patch:
diff --git a/schema_test.go b/schema_test.go
index 97e3f6f..693170c 100644
--- a/schema_test.go
+++ b/schema_test.go
@@ -83,6 +83,14 @@ func (c TypedStringWithCustomLength) Schema(r huma.Registry) *huma.Schema {
 	}
 }
 
+type TypedIntegerWithCustomLimits int
+
+func (c *TypedIntegerWithCustomLimits) TransformSchema(r huma.Registry, s *huma.Schema) *huma.Schema {
+	s.Minimum = Ptr(float64(1))
+	s.Maximum = Ptr(float64(10))
+	return s
+}
+
 func TestSchema(t *testing.T) {
 	bitSize := strconv.Itoa(bits.UintSize)
 
@@ -949,6 +957,61 @@ func TestSchema(t *testing.T) {
 				"type":"object"
 			}`,
 		},
+		{
+			name: "field-custom-limits-int",
+			input: struct {
+				Value TypedIntegerWithCustomLimits `json:"value"`
+			}{},
+			expected: ` {
+					"additionalProperties":false,
+					"properties":{
+						"value":{
+							"type":"integer",
+							"format":"int64",
+							"minimum":1,
+							"maximum":10
+						}
+					},
+					"required":["value"],
+					"type":"object"
+				}`,
+		},
+		{
+			name: "field-custom-limits-int-with-tag",
+			input: struct {
+				Value TypedIntegerWithCustomLimits `json:"value" minimum:"2"`
+			}{},
+			expected: ` {
+					"additionalProperties":false,
+					"properties":{
+						"value":{
+							"type":"integer",
+							"format":"int64",
+							"minimum":2,
+							"maximum":10
+						}
+					},
+					"required":["value"],
+					"type":"object"
+				}`,
+		},
+		{
+			name: "field-ptr-to-custom-limits-int",
+			input: struct {
+				Value *TypedIntegerWithCustomLimits `json:"value"`
+			}{},
+			expected: ` {
+				"additionalProperties":false,
+				"properties":{
+					"value":{
+						"format":"int64",
+						"type": ["integer", "null"]
+					}
+				},
+				"required":["value"],
+				"type":"object"
+			}`,
+		},
 		{
 			name: "field-custom-array",
 			input: struct {