---
sidebar_class_name: sidebar-item--hidden
---

# Reference

## Generic Zog Schema Methods

These are methods that can generally be called on any schema type (Some exceptions might exist).

```go
schema.Test(test)        // create a custom test
schema.TestFunc(fn)      // create a custom test from a function
schema.Required()        // marks field as required
schema.Optional()        // marks field as optional
schema.Default(value)    // sets default value for field
schema.DefaultFunc(fn)   // sets default value for field using a function
schema.Catch(value)      // sets catch value for field
schema.CatchFunc(fn)     // sets catch value for field using a function
schema.Transform(func(valPtr *T or any, ctx z.Ctx) (any, error)) // adds a transformation function to the schema. This is useful for things like trimming strings, etc.

// VALIDATION METHODS
schema.Parse(data, destPtr) // parses the data into the destination
schema.Validate(dataPtr)    // validates the data structure directly. This is a pointer to a struct, slice, string, int, etc...
```

## Options

Utility functions used to configure schemas, executions, tests, etc...

### Test Options

These are options that can be passed to any test. For more on this checkout the [Anatomy of a Schema](/core-concepts/anatomy-of-schema#test-options) page.

```go
z.Message()       // sets the issue message for messages generated by the tests
z.MessageFunc(fn) // sets the issue message for messages generated by the tests. This is a function that takes the data as input and returns a string
z.IssueCode()     // sets the issue code for messages generated by the tests
z.IssuePath()     // sets the issue path for messages generated by the tests
```

### Schema Options

These are options that can be passed to schemas when creating them.

```go
z.WithCoercer(fn) // sets the coercer for the schema. Only does anything if using schema.Parse()
```

### Execution Options

These are options that can be passed to schema.Parse() & schema.Validate(). They configure the execution behaviour of the validation.

```go
z.WithIssueFormatter(fn) // sets the issue formatter for the execution. This is used to format the issues messages during execution.
z.WithCtxValue(key, val) // sets a value in the execution context. This is useful for passing values to tests or post transforms.
```

## Schema Types

```go
// Primitives. Calling .Parse() on these will return []ZogIssue
z.String()
z.Int()
z.Int32()
z.Int64()
z.Float32()
z.Float64()
z.Bool()
z.Time()

// Custom Primitive Schemas
z.StringLike[T]()
z.IntLike[T]()
z.FloatLike[T]()
z.UintLike[T]()
z.BoolLike[T]()

// Complex Types. Calling .Parse() on these will return ZogIssueList (same as primitives). Each issue has a Path field ([]string) indicating where the issue occurred. Root-level issues have a nil Path.
z.Struct(z.Shape{
	"name": z.String(),
})
z.Slice(z.String())
z.Ptr(z.String()) // pointer to string
z.Boxed[B, T](schema, unboxFunc, boxFunc) // boxed type wrapper
```

### Utility Schemas

```go
z.Preprocess()
// Usage:
z.Preprocess(func(data any, ctx z.ctx) (any, error) {
	s := data.(string)
	return strings.split(s, ","), nil
}, z.slice(z.string())))
```

### Primitive Types

#### String

```go
// Transforms
z.String().Trim() // trims the value of whitespace

// Tests / Validations
z.String().Test()                         // custom test
z.String().Min(5)                         // validates min length
z.String().Max(10)                        // validates max length
z.String().Len(5)                         // validates length
z.String().Email()                        // validates email
z.String().URL()                          // validates url
z.String().IPv4()                         // validates IPv4 address
z.String().UUID()                         // validates uuid v4
z.String().Match(regex)                   // matches a regex
z.String().Contains(substring)            // validates string contains substring
z.String().ContainsUpper()                // validates string contains uppercase letter
z.String().ContainsDigit()                // validates string contains digit
z.String().ContainsSpecial()              // validates string contains special character
z.String().HasPrefix(prefix)              // validates string has prefix
z.String().HasSuffix(suffix)              // validates string has suffix
z.String().OneOf([]string{"a", "b", "c"}) // validates string is one of the values. Similar to zod enums

// Utilities
z.String().Not() // Negates the next test/validation
```

#### Numbers / Ints & Floats

```go
// Supported out of the box (see custom schemas for comparable types):
z.Int()
z.Int32()
z.Int64()
z.Float32()
z.Float64()


// Tests / Validators
z.Int().GT(n)                             // validates int is greater than n
z.Float().GTE(n)                          // validates float is greater than or equal to n
z.Int().LT(n)                             // validates int is less than n
z.Float().LTE(n)                          // validates float is less than or equal to n
z.Int().EQ(n)                             // validates int is equal to n
z.Float().OneOf([]float64{1.0, 2.0, 3.0}) // validates float is one of the values. Similar to zod enums

// Utilities
z.Int().Not()   // Negates the next test/validation
z.Float().Not() // Negates the next test/validation
```

#### Booleans

```go
// Tests / Validators
z.Bool().True()   // validates bool is true
z.Bool().False()  // validates bool is false
z.Bool().EQ(true) // validates bool is equal to true
```

### Times & Dates

Use Time to validate `time.Time` instances

```go
// Tests / Validators
z.Time().After(time.Now())  // validates time is after now
z.Time().Before(time.Now()) // validates time is before now
z.Time().Is(time.Now())     // validates time is equal to now

// Schema Options
z.Time(z.Time.Format(time.RFC3339)) // If input is a string, it will be parsed as a time.Time using the provided layout. time.RFC3339 is the default. Keep in mind this coercion only works when using Parse()
```

### Complex Types

#### Structs

> Note structs cannot be required or optional. They just pass through to the underlying ZogSchemas for their fields. If you need to express that a struct might exist and if it does it must be valid, you can use a pointer. i.e `z.Ptr(z.Struct(z.Shape{...}))`

```go
// usage
s := z.Struct(z.Shape{
	"name": String().Required(),
	"age":  Int().Required(),
})

// UTILITIES
schema.Pick("key1", map[string]bool{"a": true, "b": false}) // creates a new shallow copy of the schema with only the specified fields. It supports both string keys and map[string]bool
schema.Omit("key1", map[string]bool{"a": true, "b": false}) // creates a new shallow copy of the schema omitting the specified fields. It supports both string keys and map[string]bool

schema.Extend(z.Shape{"a": z.String()}) // creates a new shallow copy of the schema with the additional fields
schema.Merge(otherSchema, otherSchema2)  // merges two or more schemas into a new schema. Last schema takes precedence for conflicting keys
// Tests / Validators
// None right now
```

#### Slices

```go
// usage
schema := z.Slice(String())

// Tests / Validators
z.Slice(Int()).Min(5)             // validates slice has at least 5 elements
z.Slice(Float()).Max(5)           // validates slice has at most 5 elements
z.Slice(Bool()).Length(5)         // validates slice has exactly 5 elements
z.Slice(String()).Contains("foo") // validates slice contains the element "foo"

// Utilities
z.Slice(String()).Not() // Negates the next test/validation
```

#### Pointers

```go
z.Ptr(z.String())          // validates pointer to string
z.Ptr(z.Slice(z.String())) // validates pointer to slice of strings

// Tests / Validators
z.Ptr(z.String()).NotNil() // Validates pointer is not nil. This is equivalent to Required() for other types
```

#### Boxed Types

Boxed schemas allow you to wrap any Zog schema with custom box/unbox logic. This is useful for working with types that wrap primitive values (like `sql.NullString`) or implementing custom value extraction patterns (like the `driver.Valuer` interface).

```go
// Function signatures
type UnboxFunc[B any, T any] func(data B, ctx Ctx) (T, error)
type CreateBoxFunc[T any, B any] func(data T, ctx Ctx) (B, error)

z.Boxed[B, T](schema ZogSchema, unboxFunc UnboxFunc[B, T], boxFunc CreateBoxFunc[T, B]) *BoxedSchema[B, T]
```

**Parameters:**

- `B`: The boxed type (the wrapper type)
- `T`: The inner type (the type that the schema validates)
- `schema`: The Zog schema to validate the inner type
- `unboxFunc`: Function to extract the inner value from the box
- `boxFunc`: Function to create a new box from the validated inner value

**Usage Examples:**

```go
//
//
// Example 1: driver.Valuer pattern
//
//

type StringValuer interface {
	Value() (string, error)
}

schema := z.Boxed(
	z.String().Min(3),
	func(b StringValuer, ctx z.Ctx) (string, error) { return b.Value() },
	func(s string, ctx z.Ctx) (StringValuer, error) { return myStringValuer{v: s}, nil }, // you can pass nil here if you don't need to box values.
)

var valuer StringValuer
schema.Parse("hello", &valuer) // valuer.Value() will be "hello"
valuer = createValuer("hello2")
schema.Validate(&valuer) // valuer.Value() will be "hello2"


// Example 2: Nullable pattern (like sql.NullString)
type NullString struct {
	String string
	Valid  bool
}

schema := z.Boxed(
	z.String().Min(3),
	func(ns NullString, ctx z.Ctx) (string, error) {
		if !ns.Valid {
			return "", errors.New("null string is not valid")
		}
		return ns.String, nil
	},
	func(s string, ctx z.Ctx) (NullString, error) {
		return NullString{String: s, Valid: true}, nil
	},
)

// Example 3: Omittable pattern

type Omittable[T any] interface {
	Value() T
	IsSet() bool
}

schema := z.Boxed(
	z.Ptr(z.String().Min(3)),
	func(o Omittable[string], ctx z.Ctx) (*string, error) {
		if o.IsSet() {
			val := o.Value()
			return &val, nil
		}
		return nil, nil
	},
	func(s *string, ctx z.Ctx) (Omittable[string], error) {
		return createOmittable(s), nil
	},
)
```

**Parse vs Validate:**

- **Parse**: Accepts raw data, box values (`B`), or pointers to boxes (`*B`). If the input is a box, it unboxes it first before processing. The value will be boxed back into the original type if a `boxFunc` is provided.
- **Validate**: Validates an existing box value, applies transformations, and re-boxes the result back into the original box if a `boxFunc` is provided.

**Notes:**

- Transforms, defaults, catch values, and all other schema features work normally and propagate back to the box
- Boxed schemas can be nested inside Struct schemas
- The `boxFunc` is called after validation/transformation to create the final boxed value
