zog

package module
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2024 License: MIT Imports: 11 Imported by: 4

README

ZOG - A Zod & Yup like Schema Parser & Validator for GO

Coverage Status Go Report Card GitHub tag Go Reference

Mentioned in Awesome Go Mentioned in Awesome Templ stars - zog

view - Documentation

Zog is a schema builder for runtime value parsing and validation. Define a schema, transform a value to match, assert the shape of an existing value, or both. Zog schemas are extremely expressive and allow modeling complex, interdependent validations, or value transformations. Checkout the full docs at https://zog.dev

Killer Features:

  • Concise yet expressive schema interface, equipped to model simple to complex data models
  • Zod-like API, use method chaining to build schemas in a typesafe manner
  • Extensible: add your own validators, schemas and data providers
  • Rich error details, make debugging a breeze
  • Almost no reflection when using primitive types
  • Built-in coercion support for most types
  • Zero dependencies!
  • Three Helper Packages
    • zenv: parse environment variables
    • zhttp: parse http forms & query params
    • i18n: Opinionated solution to good i18n zog errors

API Stability:

  • I will consider the API stable when we reach v1.0.0
  • However, I believe very little API changes will happen from the current implementation. The APIs are are most likely to change are the data providers (please don't make your own if possible use the helpers whose APIs will not change meaningfully) and the ParseCtx most other APIs should remain the same
  • Zog will not respect semver until v1.0.0 is released. Expect breaking changes (mainly in non basic apis) until then.

Introduction

0. Read the docs at zog.dev

Or don't, below is the quickstart guide

1 Install
go get github.com/Oudwins/zog
2 Create a user schema and its struct
import (
  z "github.com/Oudwins/zog"
   )


type User struct {
  Name string `zog:"firstname"` // tag is optional. If not set zog will check for "name" field in the input data
  Age int
}

var userSchema = z.Struct(z.Schema{
  // its very important that schema keys like "name" match the struct field name NOT the input data
  "name": z.String().Min(3, z.Message("Override default message")).Max(10),
  "age": z.Int().GT(18).Required(z.Message("is required")),
})
3 Parse into the struct
func main() {
  u := User{}
  m := map[string]string{
    "firstname": "Zog", // Note we are using "firstname" here as specified in the struct tag
    "age": "", // won't return an error because fields are optional by default
  }
  errsMap := schema.Parse(m, &u)
  if errsMap != nil {
    // handle errors -> see Errors section
  }
  u.Name // "Zog"
  // note that this might look weird but we didn't say age was required so Zog just skiped the empty string and we are left with the uninitialized int
  u.Age // 0
}
4. Its easy to use with http

The zhttp package has you covered for JSON, Forms and Query Params, just do:

import (
  zhttp "github.com/Oudwins/zog/zhttp"
   )
err := userSchema.Parse(zhttp.Request(r), &user)
5. Or to validate your environment variables

The zenv package has you covered, just do:

import (
  zenv "github.com/Oudwins/zog/zenv"
   )
err := envSchema.Parse(zenv.NewDataProvider(), &envs)
6. You can also parse individual fields
var t = time.Time
errsList := Time().Required().Parse("2020-01-01T00:00:00Z", &t)
7 And do stuff before and after parsing
var dest []string
Slice(String().Email().Required()).PreTransform(func(data any, ctx z.ParseCtx) (any, error) {
  s := val.(string)
  return strings.Split(s, ","), nil
}).PostTransform(func(destPtr any, ctx z.ParseCtx) error {
  s := val.(*[]string)
  for i, v := range s {
    s[i] = strings.TrimSpace(v)
  }
  return nil
}).Parse("foo@bar.com,bar@foo.com", &dest) // dest = [foo@bar.com bar@foo.com]

Roadmap

These are some of the things I want to add to zog before v1.0.0

  • For structs & slices: support pointers
  • Support for schema.Clone()
  • support for catch & default for structs & slices
  • Struct generation from the schemas
  • Validate method that will not parse but rather just validate a struct against the schema

Support

The damm domain costs me some outrageous amount like 100$ a year, so if any one wants to help cover that cost through github sponsors that is more than welcome.

Acknowledgments

  • Big thank you to @AlexanderArvidsson for being there to talk about architecture and design decisions. It helped a lot to have someone to bounce ideas off of
  • Credit for all the inspiration goes to /colinhacks/zod & /jquense/yup
  • Credit for the initial idea goes to anthony (@anthonyGG) -> /anthdm/superkit he made a hacky version of this idea that I used as a starting point, I was never happy with it so I inspired me to rewrite it from scratch. I owe him a lot
  • Credit for the zod logo goes to /colinhacks/zod

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Errors = errHelpers{}

Helper struct for dealing with zog errors. Beware this API may change

Functions

func Bool

func Bool(opts ...SchemaOption) *boolProcessor

Returns a new Bool Schema

func Float

func Float(opts ...SchemaOption) *numberProcessor[float64]

creates a new float64 schema

func Int

func Int(opts ...SchemaOption) *numberProcessor[int]

creates a new int schema

func NewMapDataProvider

func NewMapDataProvider[T any](m map[string]T) p.DataProvider

Creates a new map data provider

func Ptr added in v0.12.1

func Ptr(schema ZogSchema) *pointerProcessor

Ptr creates a pointer ZogSchema

func Slice

func Slice(schema ZogSchema, opts ...SchemaOption) *sliceProcessor

func String

func String(opts ...SchemaOption) *stringProcessor

Returns a new String Schema

func Struct

func Struct(schema Schema) *structProcessor

Returns a new structProcessor which can be used to parse input data into a struct

func TestFunc

func TestFunc(errCode zconst.ZogErrCode, validateFunc p.TestFunc) p.Test

TestFunc is a helper function to define a custom test. It takes the error code which will be used for the error message and a validate function. Usage:

schema.Test(z.TestFunc(zconst.ErrCodeCustom, func(val any, ctx ParseCtx) bool {
	return val == "hello"
}))

Types

type Numeric

type Numeric interface {
	~int | ~float64
}

type ParseCtx

type ParseCtx = p.ParseCtx

ParseCtx is the context passed through the parser

type ParsingOption

type ParsingOption = func(p *p.ZogParseCtx)

Options that can be passed to a `schema.Parse()` call

func WithCtxValue

func WithCtxValue(key string, val any) ParsingOption

func WithErrFormatter

func WithErrFormatter(fmter p.ErrFmtFunc) ParsingOption

type Schema

type Schema map[string]ZogSchema

A map of field names to zog schemas

type SchemaOption added in v0.12.0

type SchemaOption = func(s ZogSchema)

Options that can be passed to a `schema.New()` call

func WithCoercer added in v0.12.0

func WithCoercer(c conf.CoercerFunc) SchemaOption

type Test

type Test = p.Test

Test is the test object

type TestOption

type TestOption = func(test *p.Test)

Options that can be passed to a test

func Message

func Message(msg string) TestOption

Message is a function that allows you to set a custom message for the test.

func MessageFunc

func MessageFunc(fn p.ErrFmtFunc) TestOption

MessageFunc is a function that allows you to set a custom message formatter for the test.

type TimeFunc added in v0.12.0

type TimeFunc func(opts ...SchemaOption) *timeProcessor
var Time TimeFunc = func(opts ...SchemaOption) *timeProcessor {
	t := &timeProcessor{
		coercer: conf.Coercers.Time,
	}
	for _, opt := range opts {
		opt(t)
	}
	return t
}

Returns a new Time Schema

func (TimeFunc) Format added in v0.12.0

func (t TimeFunc) Format(format string) SchemaOption

Sets the string format for the time schema Usage is: z.Time(z.Time.Format(time.RFC3339))

func (TimeFunc) FormatFunc added in v0.12.0

func (t TimeFunc) FormatFunc(format func(data string) (time.Time, error)) SchemaOption

Sets the format function for the time schema Usage is:

z.Time(z.Time.FormatFunc(func(data string) (time.Time, error) {
	return time.Parse(time.RFC3339, data)
}))

type ZogErrList

type ZogErrList = p.ZogErrList

ZogErrList is a []ZogError returned from parsing primitive schemas

type ZogErrMap

type ZogErrMap = p.ZogErrMap

ZogErrMap is a map[string][]ZogError returned from parsing complex schemas

type ZogError

type ZogError = p.ZogError

ZogError is the ZogError interface

type ZogSchema added in v0.12.0

type ZogSchema interface {
	// contains filtered or unexported methods
}

The ZogSchema is the interface all schemas must implement

Directories

Path Synopsis
en
es

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL