feat: support for custom strings, numbers and booleans#131
Conversation
WalkthroughThe pull request updates schema types by introducing generics for booleans and strings. The Changes
Sequence Diagram(s)sequenceDiagram
participant C as Client
participant CIS as CustomInterfaceSchema
participant PT as PreTransform
participant VT as Validation Tests
participant POT as PostTransform
C->>CIS: Parse(data)
CIS->>PT: Apply PreTransform
PT-->>CIS: Transformed data
CIS->>VT: Run Validations
VT-->>CIS: Return issues/success
alt Validation Fails
CIS->>CIS: Execute Catch/Fallback
else
CIS->>POT: Apply PostTransform
POT-->>CIS: Finalized data
end
CIS-->>C: Return result or error list
Possibly related PRs
Poem
Tip ⚡🧪 Multi-step agentic review comment chat (experimental)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
boolean.go(8 hunks)boolean_validate_test.go(1 hunks)custom.go(1 hunks)docs/docs/zog-schemas.md(1 hunks)internals/tests.go(1 hunks)numbers_custom_test.go(1 hunks)string.go(23 hunks)string_custom_test.go(1 hunks)struct_test.go(3 hunks)utils.go(2 hunks)utilsOptions_test.go(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (28)
docs/docs/zog-schemas.md (1)
150-150: Great addition of theEQ()method for boolean validation!This new method complements the existing
True()andFalse()validators by providing a more generic equality check. This is particularly useful when you need to validate against a boolean parameter rather than hardcoding the expected value.boolean_validate_test.go (1)
105-105: Correctly updated the type signature to use the new genericBoolSchema.The change from
*BoolSchemato*BoolSchema[bool]properly reflects the introduction of generics for boolean schemas, ensuring type safety while maintaining backward compatibility.utils.go (3)
6-6: Added necessary import for theconfpackage.This import is needed to support the new
CoercerFunctype alias.
40-41: Good addition of theCoercerFunctype alias.This type alias improves code organization by centralizing the coercion function type definition, making it easier to use and understand throughout the codebase.
47-47: Clear deprecation notice replacing the previous warning.The updated comment clearly marks
TestFuncas deprecated and recommends usingz.schema.TestFuncinstead, providing a better migration path for users.internals/tests.go (1)
33-33: Excellent improvement to theLengthCapableinterface.Changing
stringto~stringallows the interface to work with custom string types, not just the built-instringtype. This is a key enhancement that enables the library to support custom string types while maintaining all the validation capabilities.struct_test.go (3)
34-39: Field tags updated correctly in objTagged struct.The update to the
Timfield's tag from no tag tozog:"tim-1"is consistent with the PR objective of enhancing type handling and serialization. This change allows for more specific field mapping during serialization/deserialization.
62-67: Test data updated to match new struct tags.The test data in
TestStructTagshas been appropriately updated to use"tim-1"as the key, which corresponds to the modified struct tag. This ensures the test correctly validates the struct tag behavior.
332-336: Type definition change from Custom to CustomType is well implemented.The change from
CustomtoCustomTypeenhances type safety and makes the type naming more explicit. Constants are correctly updated to use the new type.utilsOptions_test.go (1)
83-120: Well-structured test for byte array coercion functionality.The new
TestWithCoercerfunction effectively tests the custom coercer that converts byte arrays to hexadecimal strings. The test covers both direct conversion and usage within a struct context. The implementation is robust, handling null bytes correctly.Two minor suggestions:
- Consider adding a test case with null bytes to explicitly verify that behavior.
- Consider moving the coercer function to a utility package if it's likely to be reused elsewhere.
numbers_custom_test.go (3)
11-31: Well-implemented custom integer type and schema creator.The
MyInttype andCustomIntfunction properly implement a custom integer type with appropriate coercion. The approach follows good practices for extending the schema system with custom types.
32-166: Comprehensive basic validation tests for custom integer type.The test suite thoroughly covers the basic functionality including parsing, validation, error formatting, schema options, required/optional fields, defaults, error catching, and transformations. All tests are well-structured with clear assertions.
167-315: Complete coverage of comparison operations and additional validators.The tests for numerical comparisons (OneOf, EQ, GT, GTE, LT, LTE) and custom test functions are thorough and well-implemented. The type checking in
TestCustomNumberGetTypeensures the schema maintains the correct type.string_custom_test.go (4)
11-29: Clean implementation of custom string type with appropriate schema creator.The
Envtype andMyStringSchemafunction provide a good example of how to implement custom string types. The coercer implementation correctly handles type conversion while maintaining error propagation.
31-55: Essential validation tests cover core functionality.The basic tests for optional fields, required validation, default values, and catch behavior are well-implemented and ensure the fundamental functionality works correctly.
57-77: Transformation tests verify both pre and post processing.The pre-transform and post-transform tests confirm that values can be manipulated both before and after validation, which is essential for flexible schema handling.
79-148: Comprehensive validation tests for string-specific validators.The tests thoroughly cover string-specific validations including length constraints, content validation (contains, prefix, suffix), regex matching, enum validation (OneOf), and special formats (email, URL, UUID). This provides complete coverage of the string schema capabilities.
custom.go (1)
3-43: Consider removing or uncommenting the experimental code.All lines in this section are commented out, indicating that you may be experimenting or deferring implementation. If these definitions are actually needed for schema usage or custom interface definitions, uncomment them and add tests; otherwise, consider removing them to avoid confusion or dead code.
Would you like me to search the codebase to see if these commented structs or functions are referenced elsewhere? If yes, I'll generate a shell script to verify their usage.
boolean.go (5)
9-10: Good interface conformance check.Declaring
var _ PrimitiveZogSchema[bool] = &BoolSchema[bool]{}confirms at compile-time thatBoolSchema[bool]satisfies thePrimitiveZogSchema[bool]interface. No issues here.
11-19: Generic type constraint and pointer fields.Defining
type BoolSchema[T ~bool] struct { ... }for generics is a neat way to handle boolean-like types. However, storingdefaultValandcatchas pointers can be cautious because:
- If many
BoolSchemainstances are created, referencing pointers may add slight complexity or confusion when unwrapping values.- Ensure there's no concurrency scenario where these pointers are modified.
Otherwise, this approach is consistent with the rest of the code.
36-44: Constructor approach looks consistent.The
Bool(opts ...SchemaOption)function returns a*BoolSchema[bool]and applies options for further customization. This approach aligns well with a fluent schema-building pattern.
47-60: Parsing and validation flow delegation.Both
ParseandValidatemethods delegate core logic toprimitiveProcessorandprimitiveValidator(viaprocessandvalidate). This is a systematic approach for code reuse. Ensure:
- The transformations and tests that rely on these calls are thoroughly covered by tests.
- That any special-case overrides or expansions (e.g., custom boolean constraints) are properly tested as well.
Also applies to: 63-66, 68-81, 84-86
155-159: Equality checks are straightforward and clear.
True(),False(), andEQ(val T)all append equality tests. This is a simple, discoverable API for boolean constraints. Just ensurep.EQ[T]is robust for all forms of boolean-like inputs you plan to support.Also applies to: 160-164, 165-168
string.go (5)
13-13: Generic type constraint for string-like types.Switching to
type StringSchema[T ~string]allows flexible usage of any type whose underlying type isstring. StoringdefaultValandcatchas pointers is consistent with the boolean schema, but watch for clarity when you unmarshal the values. Overall, this design parallels the boolean schema changes, maintaining consistency.Also applies to: 20-28
108-119: Ensure casting safety in Trim pre-transform.The snippet:
case T: return T(strings.TrimSpace(string(v))), nilrelies on
Tbeing convertible tostringand vice versa. This should be safe givenT ~string, but be mindful of potential edge cases with custom string types. No immediate issues, just a reminder to test thoroughly.
221-237: Robust email and URL validation checks.The
Email()andURL()methods parse the pointer toTand cast it to astringfor regex or URL parsing checks. This approach looks correct; just ensure edge cases (e.g., empty strings, unusual URLs) are tested thoroughly.Also applies to: 240-257
260-299: Substring and character checks appear correct.The methods
HasPrefix,HasSuffix,Contains,ContainsUpper,ContainsDigit, andContainsSpecialeach parse the pointer toT, then rely onstringsor character checks. This pattern is clear and consistent. Verify boundary cases (e.g., empty or single-character strings) in your tests to ensure correct reporting of issues.Also applies to: 301-320, 322-344, 346-370, 372-398
400-417: UUID and regex matching logic.
UUID()andMatch(regex)likewise parse*Tand run their respective checks. Your approach to handle parse failures withok == falsereturningfalseis consistent. Confirm defensive tests exist for incorrectly structured data.Also applies to: 419-438
custom.go
Outdated
| // func (v *CustomInterfaceSchema) Parse(data any, destPtr any, options ...ExecOption) ZogIssueList { | ||
| // errs := p.NewErrsList() | ||
| // defer errs.Free() | ||
|
|
||
| // ctx := p.NewExecCtx(errs, conf.IssueFormatter) | ||
| // defer ctx.Free() | ||
| // for _, opt := range options { | ||
| // opt(ctx) | ||
| // } | ||
|
|
||
| // path := p.NewPathBuilder() | ||
| // defer path.Free() | ||
| // v.process(ctx.NewSchemaCtx(data, destPtr, path, v.getType())) | ||
|
|
||
| // return errs.List | ||
| // } | ||
|
|
||
| // func (v *CustomInterfaceSchema) process(ctx *p.SchemaCtx) { | ||
| // defer ctx.Free() | ||
| // canCatch := v.catch != nil | ||
| // // 4. postTransforms | ||
| // defer func() { | ||
| // // only run posttransforms on success | ||
| // if !ctx.HasErrored() { | ||
| // for _, fn := range v.postTransforms { | ||
| // err := fn(ctx.Val, ctx) | ||
| // if err != nil { | ||
| // ctx.AddIssue(ctx.IssueFromUnknownError(err)) | ||
| // return | ||
| // } | ||
| // } | ||
| // } | ||
| // }() | ||
|
|
||
| // // 1. preTransforms | ||
| // for _, fn := range v.preTransforms { | ||
| // nVal, err := fn(ctx.Val, ctx) | ||
| // // bail if error in preTransform | ||
| // if err != nil { | ||
| // if canCatch { | ||
| // v.definition.SetValue(ctx.Val, v.catch) | ||
| // return | ||
| // } | ||
| // ctx.AddIssue(ctx.IssueFromUnknownError(err)) | ||
| // return | ||
| // } | ||
| // v.definition.SetValue(ctx.Val, nVal) | ||
| // } | ||
|
|
||
| // // 2. cast data to string & handle default/required | ||
| // // Warning. This uses generic IsZeroValue because for Validate we treat zero values as invalid for required fields. This is different from Parse. | ||
| // isZeroVal := p.IsZeroValue(ctx.Val) | ||
|
|
||
| // if isZeroVal { | ||
| // if v.defaultVal != nil { | ||
| // v.definition.SetValue(ctx.Val, v.defaultVal) | ||
| // } else if v.required == nil { | ||
| // // This handles optional case | ||
| // return | ||
| // } else { | ||
| // // is required & zero value | ||
| // // required | ||
| // if v.catch != nil { | ||
| // v.definition.SetValue(ctx.Val, v.catch) | ||
| // return | ||
| // } else { | ||
| // ctx.AddIssue(ctx.IssueFromTest(v.required, ctx.Val)) | ||
| // return | ||
| // } | ||
| // } | ||
| // } | ||
| // // 3. tests | ||
| // for _, test := range v.tests { | ||
| // if !test.ValidateFunc(ctx.Val, ctx) { | ||
| // // catching the first error if catch is set | ||
| // if canCatch { | ||
| // v.definition.SetValue(ctx.Val, v.catch) | ||
| // return | ||
| // } | ||
| // ctx.AddIssue(ctx.IssueFromTest(&test, ctx.Val)) | ||
| // } | ||
| // } | ||
|
|
||
| // } | ||
|
|
||
| // // Validate Given string | ||
| // func (v *CustomInterfaceSchema) Validate(dataPtr any, options ...ExecOption) p.ZogIssueList { | ||
| // errs := p.NewErrsList() | ||
| // defer errs.Free() | ||
| // ctx := p.NewExecCtx(errs, conf.IssueFormatter) | ||
| // defer ctx.Free() | ||
| // for _, opt := range options { | ||
| // opt(ctx) | ||
| // } | ||
|
|
||
| // path := p.NewPathBuilder() | ||
| // defer path.Free() | ||
| // v.validate(ctx.NewSchemaCtx(dataPtr, dataPtr, path, v.getType())) | ||
| // return errs.List | ||
| // } | ||
|
|
||
| // // Internal function to validate the data | ||
| // func (v *CustomInterfaceSchema) validate(ctx *p.SchemaCtx) { | ||
| // defer ctx.Free() | ||
| // canCatch := v.catch != nil | ||
|
|
||
| // // 4. postTransforms | ||
| // defer func() { | ||
| // // only run posttransforms on success | ||
| // if !ctx.HasErrored() { | ||
| // for _, fn := range v.postTransforms { | ||
| // err := fn(ctx.Val, ctx) | ||
| // if err != nil { | ||
| // ctx.AddIssue(ctx.IssueFromUnknownError(err)) | ||
| // return | ||
| // } | ||
| // } | ||
| // } | ||
| // }() | ||
|
|
||
| // // 1. preTransforms | ||
| // for _, fn := range v.preTransforms { | ||
| // nVal, err := fn(ctx.Val, ctx) | ||
| // // bail if error in preTransform | ||
| // if err != nil { | ||
| // if canCatch { | ||
| // v.definition.SetValue(ctx.Val, v.catch) | ||
| // return | ||
| // } | ||
| // ctx.AddIssue(ctx.IssueFromUnknownError(err)) | ||
| // return | ||
| // } | ||
| // v.definition.SetValue(ctx.Val, nVal) | ||
| // } | ||
|
|
||
| // // 2. cast data to string & handle default/required | ||
| // // Warning. This uses generic IsZeroValue because for Validate we treat zero values as invalid for required fields. This is different from Parse. | ||
| // isZeroVal := p.IsZeroValue(ctx.Val) | ||
|
|
||
| // if isZeroVal { | ||
| // if v.defaultVal != nil { | ||
| // v.definition.SetValue(ctx.Val, v.defaultVal) | ||
| // } else if v.required == nil { | ||
| // // This handles optional case | ||
| // return | ||
| // } else { | ||
| // // is required & zero value | ||
| // // required | ||
| // if v.catch != nil { | ||
| // v.definition.SetValue(ctx.Val, v.catch) | ||
| // return | ||
| // } else { | ||
| // ctx.AddIssue(ctx.IssueFromTest(v.required, ctx.Val)) | ||
| // return | ||
| // } | ||
| // } | ||
| // } | ||
| // // 3. tests | ||
| // for _, test := range v.tests { | ||
| // if !test.ValidateFunc(ctx.Val, ctx) { | ||
| // // catching the first error if catch is set | ||
| // if canCatch { | ||
| // v.definition.SetValue(ctx.Val, v.catch) | ||
| // return | ||
| // } | ||
| // ctx.AddIssue(ctx.IssueFromTest(&test, ctx.Val)) | ||
| // } | ||
| // } | ||
|
|
||
| // } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Ensure code alignment with future usage and maintain consistency.
The entire parse/validate logic is currently commented out as well. If you intend to proceed with a CustomInterfaceSchema, confirm the approach is consistent with your other schemas (e.g., BoolSchema and StringSchema). For instance, you may need to confirm:
- How data transformations and tests will integrate with the rest of the codebase.
- Whether the fallback (
catch) and default values are coherent with other schema patterns. - That you have adequate unit tests to guarantee reliable field parsing.
If this logic is truly experimental, consider placing it in a branch or feature flag to prevent confusion in production code.
Deploying zog with
|
| Latest commit: |
4d140f4
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://331614a5.zog-3a0.pages.dev |
| Branch Preview URL: | https://feat-custom-types.zog-3a0.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (6)
docs/docs/custom-schemas.md (6)
11-11: Grammar Improvement: Missing Comma After "Currently"
Consider adding a comma right after "Currently" to improve readability.-Currently Zog plans to support three different ways... +Currently, Zog plans to support three different ways...
17-20: Section Introduction: Tone Adjustment
The phrase "This is quite simple" could be simplified to "This is simple" to avoid an over-used intensifier.🧰 Tools
🪛 LanguageTool
[style] ~19-~19: As an alternative to the over-used intensifier ‘quite’, consider replacing this phrase.
Context: ...om Schemas for Primitive Types This is quite simple to do for the supported primitive types...(EN_WEAK_ADJECTIVE)
21-41: Formatting: Replace Hard Tabs with Spaces
Static analysis indicates that hard tabs are used in the Go code examples. Replacing these with spaces will improve markdown consistency and adhere to common style guidelines.Also applies to: 45-66
43-44: Sentence Structure: Insert Comma Before "and"
In the sentence introducing the Coercer example, a comma before "and" will help separate the independent clauses for better clarity.-Here is what I would recommend and it is also very similar to the way Zog creates the schemas you use: +Here is what I would recommend, and it is also very similar to the way Zog creates the schemas you use:🧰 Tools
🪛 LanguageTool
[uncategorized] ~43-~43: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...function. Here is what I would recommend and it is also very similar to the way Zog ...(COMMA_COMPOUND_SENTENCE)
45-66: Code Example (Coercer Function): Variable Declaration and Go Idioms
The example is informative; however, note that the variableopsis used without an explicit declaration. For clarity and to follow Go conventions, consider declaring it (e.g., usingops := append(...)).🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
48-48: Hard tabs
Column: 1(MD010, no-hard-tabs)
49-49: Hard tabs
Column: 1(MD010, no-hard-tabs)
50-50: Hard tabs
Column: 1(MD010, no-hard-tabs)
51-51: Hard tabs
Column: 1(MD010, no-hard-tabs)
52-52: Hard tabs
Column: 1(MD010, no-hard-tabs)
53-53: Hard tabs
Column: 1(MD010, no-hard-tabs)
54-54: Hard tabs
Column: 1(MD010, no-hard-tabs)
55-55: Hard tabs
Column: 1(MD010, no-hard-tabs)
56-56: Hard tabs
Column: 1(MD010, no-hard-tabs)
57-57: Hard tabs
Column: 1(MD010, no-hard-tabs)
58-58: Hard tabs
Column: 1(MD010, no-hard-tabs)
59-59: Hard tabs
Column: 1(MD010, no-hard-tabs)
60-60: Hard tabs
Column: 1(MD010, no-hard-tabs)
61-61: Hard tabs
Column: 1(MD010, no-hard-tabs)
62-62: Hard tabs
Column: 1(MD010, no-hard-tabs)
63-63: Hard tabs
Column: 1(MD010, no-hard-tabs)
68-70: Grammar Improvement: Plural Agreement and Possessive Correction
In the closing note, update "this types of schemas" to "these types of schemas" and change "schema's" to "schemas" to correct grammatical errors.-... an API that would allow you to define this types of schemas in a more concise way (and we may still do so), to keep code consistency & reusability we recommend that you make a factory function like the one above for your custom types. And we felt that providing a simpler API could lead to people just inlining the schema's which would make it impossible to reuse them. +... an API that would allow you to define these types of schemas in a more concise way (and we may still do so), to keep code consistency & reusability we recommend that you make a factory function like the one above for your custom types. And we felt that providing a simpler API could lead to people just inlining the schemas which would make it impossible to reuse them.🧰 Tools
🪛 LanguageTool
[grammar] ~69-~69: The singular determiner ‘this’ does not agree with the plural noun ‘types’. Did you mean to write ‘these’?
Context: ...g an API that would allow you to define this types of schemas in a more concise way ...(THIS_PLURAL_OF)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
docs/docs/configuration.md(1 hunks)docs/docs/context.mdx(1 hunks)docs/docs/custom-schemas.md(1 hunks)docs/docs/errors.md(1 hunks)docs/docs/performance.md(1 hunks)docs/docs/zog-schemas.md(2 hunks)
✅ Files skipped from review due to trivial changes (4)
- docs/docs/configuration.md
- docs/docs/performance.md
- docs/docs/context.mdx
- docs/docs/errors.md
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/docs/zog-schemas.md
🧰 Additional context used
🪛 LanguageTool
docs/docs/custom-schemas.md
[uncategorized] ~10-~10: A comma may be missing after the conjunctive/linking adverb ‘Currently’.
Context: ...omy-of-schema) page before continuing. Currently Zog plans to support three different wa...
(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
[style] ~19-~19: As an alternative to the over-used intensifier ‘quite’, consider replacing this phrase.
Context: ...om Schemas for Primitive Types This is quite simple to do for the supported primitive types...
(EN_WEAK_ADJECTIVE)
[uncategorized] ~43-~43: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...function. Here is what I would recommend and it is also very similar to the way Zog ...
(COMMA_COMPOUND_SENTENCE)
[grammar] ~69-~69: The singular determiner ‘this’ does not agree with the plural noun ‘types’. Did you mean to write ‘these’?
Context: ...g an API that would allow you to define this types of schemas in a more concise way ...
(THIS_PLURAL_OF)
🪛 markdownlint-cli2 (0.17.2)
docs/docs/custom-schemas.md
48-48: Hard tabs
Column: 1
(MD010, no-hard-tabs)
49-49: Hard tabs
Column: 1
(MD010, no-hard-tabs)
50-50: Hard tabs
Column: 1
(MD010, no-hard-tabs)
51-51: Hard tabs
Column: 1
(MD010, no-hard-tabs)
52-52: Hard tabs
Column: 1
(MD010, no-hard-tabs)
53-53: Hard tabs
Column: 1
(MD010, no-hard-tabs)
54-54: Hard tabs
Column: 1
(MD010, no-hard-tabs)
55-55: Hard tabs
Column: 1
(MD010, no-hard-tabs)
56-56: Hard tabs
Column: 1
(MD010, no-hard-tabs)
57-57: Hard tabs
Column: 1
(MD010, no-hard-tabs)
58-58: Hard tabs
Column: 1
(MD010, no-hard-tabs)
59-59: Hard tabs
Column: 1
(MD010, no-hard-tabs)
60-60: Hard tabs
Column: 1
(MD010, no-hard-tabs)
61-61: Hard tabs
Column: 1
(MD010, no-hard-tabs)
62-62: Hard tabs
Column: 1
(MD010, no-hard-tabs)
63-63: Hard tabs
Column: 1
(MD010, no-hard-tabs)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (3)
docs/docs/custom-schemas.md (3)
1-6: Front Matter Block: Format and Consistency
The YAML front matter appears correctly formatted with appropriate configuration for sidebar position and table of contents levels.
7-10: Header and Introductory Note: Readability
The header and the note urging readers to visit the "[Anatomy of a Schema]" page are clear and engaging.🧰 Tools
🪛 LanguageTool
[uncategorized] ~10-~10: A comma may be missing after the conjunctive/linking adverb ‘Currently’.
Context: ...omy-of-schema) page before continuing. Currently Zog plans to support three different wa...(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
13-16: List of Methods: Clarity
The three methods for creating custom schemas are clearly listed. No changes required.
| ```go | ||
| // definition in your code | ||
| type Env string | ||
| const ( | ||
| Prod Env = "prod". | ||
| Dev Env = "env" | ||
| ) | ||
| func EnvSchema() *StringSchema[Env] { | ||
| s := &z.StringSchema[Env] | ||
| return s.OneOf([]Env{Prod, Dev}) // you can also just return the schema and define the tests when calling it it doesn't matter | ||
| } | ||
| // usage | ||
| type S struct { | ||
| Environment Env | ||
| } | ||
| schema := z.Struct( | ||
| z.Schema{ | ||
| "Environment": EnvSchema() // All string methods will now be typed to Env type | ||
| } | ||
| ) | ||
| ``` |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Code Example (Primitive Types): Go Syntax and Consistency
- In line 25, the constant declaration uses an extraneous period (
"prod".). It is recommended to remove the period. - In line 29, the instantiation
s := &z.StringSchema[Env]may be more idiomatically written ass := &z.StringSchema[Env]{}to clearly initialize a new instance.
- Prod Env = "prod".
+ Prod Env = "prod"
- s := &z.StringSchema[Env]
+ s := &z.StringSchema[Env]{}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ```go | |
| // definition in your code | |
| type Env string | |
| const ( | |
| Prod Env = "prod". | |
| Dev Env = "env" | |
| ) | |
| func EnvSchema() *StringSchema[Env] { | |
| s := &z.StringSchema[Env] | |
| return s.OneOf([]Env{Prod, Dev}) // you can also just return the schema and define the tests when calling it it doesn't matter | |
| } | |
| // usage | |
| type S struct { | |
| Environment Env | |
| } | |
| schema := z.Struct( | |
| z.Schema{ | |
| "Environment": EnvSchema() // All string methods will now be typed to Env type | |
| } | |
| ) | |
| ``` |
Summary by CodeRabbit
New Features
Documentation