Codegen: Render constraints in generated docs (#63196)

* Add constraints rendering

* Generate docs

* Fix constraint format

* Add type alias

* Compare numbers as strings

* fixup! Compare numbers as strings

* Add missing return
This commit is contained in:
Tania 2023-02-10 12:40:50 +01:00 committed by GitHub
parent 7f6a1c06a6
commit f0333ac41f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 131 additions and 45 deletions

View File

@ -21,7 +21,7 @@ title: AnnotationsListPanelCfg kind
| Property | Type | Required | Description |
|-------------------------|----------|----------|-------------------|
| `limit` | integer | **Yes** | Default: `10`. |
| `limit` | uint32 | **Yes** | Default: `10`. |
| `navigateAfter` | string | **Yes** | Default: `10m`. |
| `navigateBefore` | string | **Yes** | Default: `10m`. |
| `navigateToPanel` | boolean | **Yes** | Default: `true`. |

View File

@ -32,10 +32,10 @@ It extends [AxisConfig](#axisconfig) and [HideableFieldConfig](#hideablefieldcon
| `axisSoftMax` | number | No | *(Inherited from [AxisConfig](#axisconfig))* |
| `axisSoftMin` | number | No | *(Inherited from [AxisConfig](#axisconfig))* |
| `axisWidth` | number | No | *(Inherited from [AxisConfig](#axisconfig))* |
| `fillOpacity` | integer | No | Controls the fill opacity of the bars. Default: `80`. |
| `fillOpacity` | integer | No | Controls the fill opacity of the bars. Default: `80`.<br/>Constraint: `>=0 & <=100`. |
| `gradientMode` | string | No | TODO docs<br/>Possible values are: `none`, `opacity`, `hue`, `scheme`. |
| `hideFrom` | [HideSeriesConfig](#hideseriesconfig) | No | *(Inherited from [HideableFieldConfig](#hideablefieldconfig))*<br/>TODO docs |
| `lineWidth` | integer | No | Controls line width of the bars. Default: `1`. |
| `lineWidth` | integer | No | Controls line width of the bars. Default: `1`.<br/>Constraint: `>=0 & <=10`. |
| `scaleDistribution` | [ScaleDistributionConfig](#scaledistributionconfig) | No | *(Inherited from [AxisConfig](#axisconfig))*<br/>TODO docs |
| `thresholdsStyle` | [GraphThresholdsStyleConfig](#graphthresholdsstyleconfig) | No | TODO docs |
@ -97,21 +97,21 @@ It extends [OptionsWithLegend](#optionswithlegend) and [OptionsWithTooltip](#opt
| Property | Type | Required | Description |
|-----------------------|-------------------------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------|
| `barWidth` | number | **Yes** | Controls the width of bars. 1 = Max width, 0 = Min width. Default: `0.97`. |
| `barWidth` | number | **Yes** | Controls the width of bars. 1 = Max width, 0 = Min width. Default: `0.97`.<br/>Constraint: `>=0 & <=1`. |
| `fullHighlight` | boolean | **Yes** | Enables mode which highlights the entire bar area and shows tooltip when cursor<br/>hovers over highlighted area Default: `false`. |
| `groupWidth` | number | **Yes** | Controls the width of groups. 1 = max with, 0 = min width. Default: `0.7`. |
| `groupWidth` | number | **Yes** | Controls the width of groups. 1 = max with, 0 = min width. Default: `0.7`.<br/>Constraint: `>=0 & <=1`. |
| `legend` | [VizLegendOptions](#vizlegendoptions) | **Yes** | *(Inherited from [OptionsWithLegend](#optionswithlegend))*<br/>TODO docs |
| `orientation` | string | **Yes** | TODO docs<br/>Possible values are: `auto`, `vertical`, `horizontal`. |
| `showValue` | string | **Yes** | TODO docs<br/>Possible values are: `auto`, `never`, `always`. |
| `stacking` | string | **Yes** | TODO docs<br/>Possible values are: `none`, `normal`, `percent`. |
| `tooltip` | [VizTooltipOptions](#viztooltipoptions) | **Yes** | *(Inherited from [OptionsWithTooltip](#optionswithtooltip))*<br/>TODO docs |
| `xTickLabelMaxLength` | integer | **Yes** | Sets the max length that a label can have before it is truncated. |
| `xTickLabelRotation` | integer | **Yes** | Controls the rotation of the x axis labels. Default: `0`. |
| `barRadius` | number | No | Controls the radius of each bar. Default: `0`. |
| `xTickLabelMaxLength` | integer | **Yes** | Sets the max length that a label can have before it is truncated.<br/>Constraint: `>=0 & <=2147483647`. |
| `xTickLabelRotation` | integer | **Yes** | Controls the rotation of the x axis labels. Default: `0`.<br/>Constraint: `>=-90 & <=90`. |
| `barRadius` | number | No | Controls the radius of each bar. Default: `0`.<br/>Constraint: `>=0 & <=0.5`. |
| `colorByField` | string | No | Use the color value for a sibling field to color each bar value. |
| `text` | [VizTextDisplayOptions](#viztextdisplayoptions) | No | *(Inherited from [OptionsWithTextFormatting](#optionswithtextformatting))*<br/>TODO docs |
| `xField` | string | No | Manually select which field from the dataset to represent the x field. |
| `xTickLabelSpacing` | integer | No | Controls the spacing between x axis labels.<br/>negative values indicate backwards skipping behavior Default: `0`. |
| `xTickLabelSpacing` | int32 | No | Controls the spacing between x axis labels.<br/>negative values indicate backwards skipping behavior Default: `0`. |
### OptionsWithLegend

View File

@ -24,8 +24,8 @@ It extends [SingleStatBaseOptions](#singlestatbaseoptions).
| Property | Type | Required | Description |
|-----------------|-------------------------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------|
| `displayMode` | string | **Yes** | Enum expressing the possible display modes<br/>for the bar gauge component of Grafana UI<br/>Possible values are: `basic`, `lcd`, `gradient`. |
| `minVizHeight` | integer | **Yes** | Default: `10`. |
| `minVizWidth` | integer | **Yes** | Default: `0`. |
| `minVizHeight` | uint32 | **Yes** | Default: `10`. |
| `minVizWidth` | uint32 | **Yes** | Default: `0`. |
| `showUnfilled` | boolean | **Yes** | Default: `true`. |
| `orientation` | string | No | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*<br/>TODO docs<br/>Possible values are: `auto`, `vertical`, `horizontal`. |
| `reduceOptions` | [ReduceDataOptions](#reducedataoptions) | No | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*<br/>TODO docs |

View File

@ -40,14 +40,14 @@ title: GeomapPanelCfg kind
| `id` | string | **Yes** | Default: `zero`. |
| `allLayers` | boolean | No | Default: `true`. |
| `lastOnly` | boolean | No | |
| `lat` | integer | No | Default: `0`. |
| `lat` | int64 | No | Default: `0`. |
| `layer` | string | No | |
| `lon` | integer | No | Default: `0`. |
| `lon` | int64 | No | Default: `0`. |
| `maxZoom` | integer | No | |
| `minZoom` | integer | No | |
| `padding` | integer | No | |
| `shared` | boolean | No | |
| `zoom` | integer | No | Default: `1`. |
| `zoom` | int64 | No | Default: `1`. |
### PanelOptions

View File

@ -32,10 +32,10 @@ It extends [AxisConfig](#axisconfig) and [HideableFieldConfig](#hideablefieldcon
| `axisSoftMax` | number | No | *(Inherited from [AxisConfig](#axisconfig))* |
| `axisSoftMin` | number | No | *(Inherited from [AxisConfig](#axisconfig))* |
| `axisWidth` | number | No | *(Inherited from [AxisConfig](#axisconfig))* |
| `fillOpacity` | integer | No | Controls the fill opacity of the bars. Default: `80`. |
| `fillOpacity` | integer | No | Controls the fill opacity of the bars. Default: `80`.<br/>Constraint: `>=0 & <=100`. |
| `gradientMode` | string | No | TODO docs<br/>Possible values are: `none`, `opacity`, `hue`, `scheme`. |
| `hideFrom` | [HideSeriesConfig](#hideseriesconfig) | No | *(Inherited from [HideableFieldConfig](#hideablefieldconfig))*<br/>TODO docs |
| `lineWidth` | integer | No | Controls line width of the bars. Default: `1`. |
| `lineWidth` | integer | No | Controls line width of the bars. Default: `1`.<br/>Constraint: `>=0 & <=10`. |
| `scaleDistribution` | [ScaleDistributionConfig](#scaledistributionconfig) | No | *(Inherited from [AxisConfig](#axisconfig))*<br/>TODO docs |
### AxisConfig
@ -90,7 +90,7 @@ It extends [OptionsWithLegend](#optionswithlegend) and [OptionsWithTooltip](#opt
|----------------|-----------------------------------------|----------|----------------------------------------------------------------------------|
| `legend` | [VizLegendOptions](#vizlegendoptions) | **Yes** | *(Inherited from [OptionsWithLegend](#optionswithlegend))*<br/>TODO docs |
| `tooltip` | [VizTooltipOptions](#viztooltipoptions) | **Yes** | *(Inherited from [OptionsWithTooltip](#optionswithtooltip))*<br/>TODO docs |
| `bucketOffset` | integer | No | Offset buckets by this amount Default: `0`. |
| `bucketOffset` | int32 | No | Offset buckets by this amount Default: `0`. |
| `bucketSize` | integer | No | Size of each bucket |
| `combine` | boolean | No | Combines multiple series into a single histogram |

View File

@ -24,9 +24,9 @@ It extends [HideableFieldConfig](#hideablefieldconfig).
| Property | Type | Required | Description |
|---------------|---------------------------------------|----------|------------------------------------------------------------------------------|
| `fillOpacity` | integer | No | Default: `70`. |
| `fillOpacity` | integer | No | Default: `70`.<br/>Constraint: `>=0 & <=100`. |
| `hideFrom` | [HideSeriesConfig](#hideseriesconfig) | No | *(Inherited from [HideableFieldConfig](#hideablefieldconfig))*<br/>TODO docs |
| `lineWidth` | integer | No | Default: `0`. |
| `lineWidth` | integer | No | Default: `0`.<br/>Constraint: `>=0 & <=10`. |
### HideSeriesConfig

View File

@ -24,9 +24,9 @@ It extends [HideableFieldConfig](#hideablefieldconfig).
| Property | Type | Required | Description |
|---------------|---------------------------------------|----------|------------------------------------------------------------------------------|
| `fillOpacity` | integer | No | Default: `70`. |
| `fillOpacity` | integer | No | Default: `70`.<br/>Constraint: `>=0 & <=100`. |
| `hideFrom` | [HideSeriesConfig](#hideseriesconfig) | No | *(Inherited from [HideableFieldConfig](#hideablefieldconfig))*<br/>TODO docs |
| `lineWidth` | integer | No | Default: `1`. |
| `lineWidth` | integer | No | Default: `1`.<br/>Constraint: `>=0 & <=10`. |
### HideSeriesConfig
@ -53,7 +53,7 @@ It extends [OptionsWithLegend](#optionswithlegend) and [OptionsWithTooltip](#opt
| Property | Type | Required | Description |
|-------------|-----------------------------------------|----------|----------------------------------------------------------------------------|
| `legend` | [VizLegendOptions](#vizlegendoptions) | **Yes** | *(Inherited from [OptionsWithLegend](#optionswithlegend))*<br/>TODO docs |
| `rowHeight` | number | **Yes** | Set the height of the rows Default: `0.9`. |
| `rowHeight` | number | **Yes** | Set the height of the rows Default: `0.9`.<br/>Constraint: `>=0 & <=1`. |
| `showValue` | string | **Yes** | TODO docs<br/>Possible values are: `auto`, `never`, `always`. |
| `tooltip` | [VizTooltipOptions](#viztooltipoptions) | **Yes** | *(Inherited from [OptionsWithTooltip](#optionswithtooltip))*<br/>TODO docs |
| `colWidth` | number | No | Controls the column width Default: `0.9`. |

View File

@ -94,7 +94,7 @@ It extends [ScatterFieldConfig](#scatterfieldconfig).
| `label` | string | No | *(Inherited from [ScatterFieldConfig](#scatterfieldconfig))*<br/>TODO docs<br/>Possible values are: `auto`, `never`, `always`. |
| `lineColor` | [ColorDimensionConfig](#colordimensionconfig) | No | *(Inherited from [ScatterFieldConfig](#scatterfieldconfig))*<br/>This is actually an empty interface used mainly for naming? |
| `lineStyle` | [LineStyle](#linestyle) | No | *(Inherited from [ScatterFieldConfig](#scatterfieldconfig))*<br/>TODO docs |
| `lineWidth` | integer | No | *(Inherited from [ScatterFieldConfig](#scatterfieldconfig))* |
| `lineWidth` | integer | No | *(Inherited from [ScatterFieldConfig](#scatterfieldconfig))*<br/>Constraint: `>=0 & <=2147483647`. |
| `name` | string | No | |
| `pointColor` | [ColorDimensionConfig](#colordimensionconfig) | No | *(Inherited from [ScatterFieldConfig](#scatterfieldconfig))*<br/>This is actually an empty interface used mainly for naming? |
| `pointSize` | [ScaleDimensionConfig](#scaledimensionconfig) | No | *(Inherited from [ScatterFieldConfig](#scatterfieldconfig))* |
@ -180,7 +180,7 @@ It extends [HideableFieldConfig](#hideablefieldconfig) and [AxisConfig](#axiscon
| `label` | string | No | TODO docs<br/>Possible values are: `auto`, `never`, `always`. |
| `lineColor` | [ColorDimensionConfig](#colordimensionconfig) | No | This is actually an empty interface used mainly for naming? |
| `lineStyle` | [LineStyle](#linestyle) | No | TODO docs |
| `lineWidth` | integer | No | |
| `lineWidth` | integer | No | Constraint: `>=0 & <=2147483647`. |
| `pointColor` | [ColorDimensionConfig](#colordimensionconfig) | No | This is actually an empty interface used mainly for naming? |
| `pointSize` | [ScaleDimensionConfig](#scaledimensionconfig) | No | |
| `scaleDistribution` | [ScaleDistributionConfig](#scaledistributionconfig) | No | *(Inherited from [AxisConfig](#axisconfig))*<br/>TODO docs |
@ -222,10 +222,10 @@ It extends [BaseDimensionConfig](#basedimensionconfig).
### XYDimensionConfig
| Property | Type | Required | Description |
|-----------|----------|----------|-------------|
| `frame` | integer | **Yes** | |
| `exclude` | string[] | No | |
| `x` | string | No | |
| Property | Type | Required | Description |
|-----------|----------|----------|-----------------------------------|
| `frame` | integer | **Yes** | Constraint: `>=0 & <=2147483647`. |
| `exclude` | string[] | No | |
| `x` | string | No | |

View File

@ -17,12 +17,12 @@ A Grafana dashboard.
|------------------------|-----------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `editable` | boolean | **Yes** | Whether a dashboard is editable or not. Default: `true`. |
| `graphTooltip` | integer | **Yes** | 0 for no shared crosshair or tooltip (default).<br/>1 for shared crosshair.<br/>2 for shared crosshair AND shared tooltip.<br/>Possible values are: `0`, `1`, `2`. Default: `0`. |
| `revision` | integer | **Yes** | Version of the current dashboard data Default: `-1`. |
| `schemaVersion` | integer | **Yes** | Version of the JSON schema, incremented each time a Grafana update brings<br/>changes to said schema.<br/>TODO this is the existing schema numbering system. It will be replaced by Thema's themaVersion Default: `36`. |
| `revision` | int64 | **Yes** | Version of the current dashboard data Default: `-1`. |
| `schemaVersion` | uint16 | **Yes** | Version of the JSON schema, incremented each time a Grafana update brings<br/>changes to said schema.<br/>TODO this is the existing schema numbering system. It will be replaced by Thema's themaVersion Default: `36`. |
| `style` | string | **Yes** | Theme of dashboard.<br/>Possible values are: `dark`, `light`. Default: `dark`. |
| `annotations` | [object](#annotations) | No | TODO docs |
| `description` | string | No | Description of dashboard. |
| `fiscalYearStartMonth` | integer | No | The month that the fiscal year starts on. 0 = January, 11 = December Default: `0`. |
| `fiscalYearStartMonth` | integer | No | The month that the fiscal year starts on. 0 = January, 11 = December Default: `0`.<br/>Constraint: `>=0 & <12`. |
| `gnetId` | string | No | |
| `id` | integer | No | Unique numeric identifier for the dashboard.<br/>TODO must isolate or remove identifiers local to a Grafana instance...? |
| `links` | [DashboardLink](#dashboardlink)[] | No | TODO docs |
@ -37,7 +37,7 @@ A Grafana dashboard.
| `timezone` | string | No | Timezone of dashboard. Accepts IANA TZDB zone ID or "browser" or "utc". Default: `browser`. |
| `title` | string | No | Title of dashboard. |
| `uid` | string | No | Unique dashboard identifier that can be generated by anyone. string (8-40) |
| `version` | integer | No | Version of the dashboard, incremented each time the dashboard is updated. |
| `version` | uint32 | No | Version of the dashboard, incremented each time the dashboard is updated. |
| `weekStart` | string | No | TODO docs |
### DashboardLink
@ -68,12 +68,12 @@ TODO docs
| `expires` | string | **Yes** | TODO docs |
| `externalUrl` | string | **Yes** | TODO docs |
| `external` | boolean | **Yes** | TODO docs |
| `id` | integer | **Yes** | TODO docs |
| `id` | uint32 | **Yes** | TODO docs |
| `key` | string | **Yes** | TODO docs |
| `name` | string | **Yes** | TODO docs |
| `orgId` | integer | **Yes** | TODO docs |
| `orgId` | uint32 | **Yes** | TODO docs |
| `updated` | string | **Yes** | TODO docs |
| `userId` | integer | **Yes** | TODO docs |
| `userId` | uint32 | **Yes** | TODO docs |
| `url` | string | No | TODO docs |
### Annotations
@ -91,10 +91,10 @@ FROM: AnnotationQuery in grafana-data/src/types/annotations.ts
| Property | Type | Required | Description |
|--------------|---------------------------------------|----------|-------------------------------------------------|
| `builtIn` | integer | **Yes** | Default: `0`. |
| `builtIn` | uint8 | **Yes** | Default: `0`. |
| `datasource` | [object](#datasource) | **Yes** | Datasource to use for annotation. |
| `enable` | boolean | **Yes** | Whether annotation is enabled. Default: `true`. |
| `showIn` | integer | **Yes** | Default: `0`. |
| `showIn` | uint8 | **Yes** | Default: `0`. |
| `type` | string | **Yes** | Default: `dashboard`. |
| `hide` | boolean | No | Whether to hide annotation. Default: `false`. |
| `iconColor` | string | No | Annotation icon color. |
@ -147,7 +147,7 @@ TODO there appear to be a lot of different kinds of [template] vars here? if so
| `global` | boolean | **Yes** | Default: `false`. |
| `hide` | integer | **Yes** | Possible values are: `0`, `1`, `2`. |
| `id` | string | **Yes** | Default: `00000000-0000-0000-0000-000000000000`. |
| `index` | integer | **Yes** | Default: `-1`. |
| `index` | int32 | **Yes** | Default: `-1`. |
| `name` | string | **Yes** | |
| `skipUrlSync` | boolean | **Yes** | Default: `false`. |
| `state` | string | **Yes** | Possible values are: `NotStarted`, `Loading`, `Streaming`, `Done`, `Error`. |

View File

@ -16,14 +16,14 @@ A standalone panel
| Property | Type | Required | Description |
|-----------------|-------------------------------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------|
| `model` | [object](#model) | **Yes** | TODO: should be the same panel schema defined in dashboard<br/>Typescript: Omit<Panel, 'gridPos' &#124; 'id' &#124; 'libraryPanel'>; |
| `name` | string | **Yes** | Panel name (also saved in the model) |
| `type` | string | **Yes** | The panel type (from inside the model) |
| `name` | string | **Yes** | Panel name (also saved in the model)<br/>Constraint: `length >=1`. |
| `type` | string | **Yes** | The panel type (from inside the model)<br/>Constraint: `length >=1`. |
| `uid` | string | **Yes** | Library element UID |
| `version` | integer | **Yes** | panel version, incremented each time the dashboard is updated. |
| `description` | string | No | Panel description |
| `folderUid` | string | No | Folder UID |
| `meta` | [LibraryElementDTOMeta](#libraryelementdtometa) | No | |
| `schemaVersion` | integer | No | Dashboard version when this was saved (zero if unknown) |
| `schemaVersion` | uint16 | No | Dashboard version when this was saved (zero if unknown) |
### LibraryElementDTOMeta

View File

@ -60,7 +60,9 @@ func (j docsJenny) Generate(kind kindsys.Kind) (*codejen.File, error) {
Schemas json.RawMessage
}
}
err = json.Unmarshal(b, &obj)
dec := json.NewDecoder(bytes.NewReader(b))
dec.UseNumber()
err = dec.Decode(&obj)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal schema json: %v", err)
}
@ -109,8 +111,18 @@ type templateData struct {
// -------------------- JSON to Markdown conversion --------------------
// Copied from https://github.com/marcusolsson/json-schema-docs and slightly changed to fit the DocsJenny
type constraints struct {
Pattern string `json:"pattern"`
Maximum json.Number `json:"maximum"`
ExclusiveMinimum bool `json:"exclusiveMinimum"`
Minimum json.Number `json:"minimum"`
ExclusiveMaximum bool `json:"exclusiveMaximum"`
MinLength uint `json:"minLength"`
MaxLength uint `json:"maxLength"`
}
type schema struct {
constraints
ID string `json:"$id,omitempty"`
Ref string `json:"$ref,omitempty"`
Schema string `json:"$schema,omitempty"`
@ -480,7 +492,14 @@ func makeRows(s *schema) [][]string {
rows := make([][]string, 0, len(s.Properties))
for key, p := range s.Properties {
typeStr := propTypeStr(key, p)
alias := propTypeAlias(p)
var typeStr string
if alias != "" {
typeStr = alias
} else {
typeStr = propTypeStr(key, p)
}
// Emphasize required properties.
var required string
@ -491,7 +510,6 @@ func makeRows(s *schema) [][]string {
}
var desc string
if p.inheritedFrom != "" {
desc = fmt.Sprintf("*(Inherited from [%s](#%s))*", p.inheritedFrom, strings.ToLower(p.inheritedFrom))
}
@ -512,6 +530,10 @@ func makeRows(s *schema) [][]string {
desc += fmt.Sprintf(" Default: `%v`.", p.Default)
}
// Render a constraint only if it's not a type alias https://cuelang.org/docs/references/spec/#predeclared-identifiers
if alias == "" {
desc += constraintDescr(p)
}
rows = append(rows, []string{fmt.Sprintf("`%s`", key), typeStr, required, formatForTable(desc)})
}
@ -528,6 +550,70 @@ func makeRows(s *schema) [][]string {
return rows
}
func propTypeAlias(prop *schema) string {
if prop.Minimum == "" || prop.Maximum == "" {
return ""
}
min := prop.Minimum
max := prop.Maximum
switch {
case min == "0" && max == "255":
return "uint8"
case min == "0" && max == "65535":
return "uint16"
case min == "0" && max == "4294967295":
return "uint32"
case min == "0" && max == "18446744073709551615":
return "uint64"
case min == "-128" && max == "127":
return "int8"
case min == "-32768" && max == "32767":
return "int16"
case min == "-2147483648" && max == "2147483647":
return "int32"
case min == "-9223372036854775808" && max == "9223372036854775807":
return "int64"
default:
return ""
}
}
func constraintDescr(prop *schema) string {
if prop.Minimum != "" && prop.Maximum != "" {
var left, right string
if prop.ExclusiveMinimum {
left = ">" + prop.Minimum.String()
} else {
left = ">=" + prop.Minimum.String()
}
if prop.ExclusiveMaximum {
right = "<" + prop.Maximum.String()
} else {
right = "<=" + prop.Maximum.String()
}
return fmt.Sprintf("\nConstraint: `%s & %s`.", left, right)
}
if prop.MinLength > 0 {
left := fmt.Sprintf(">=%v", prop.MinLength)
right := ""
if prop.MaxLength > 0 {
right = fmt.Sprintf(" && <=%v", prop.MaxLength)
}
return fmt.Sprintf("\nConstraint: `length %s`.", left+right)
}
if prop.Pattern != "" {
return fmt.Sprintf("\nConstraint: must match `%s`.", prop.Pattern)
}
return ""
}
func propTypeStr(propName string, propValue *schema) string {
// If the property has AdditionalProperties, it is most likely a map type
if propValue.AdditionalProperties != nil {