Search Apps Documentation Source Content File Folder Download Copy Actions Download

validation.gno

2.77 Kb · 114 lines
  1package chunk
  2
  3import "strconv"
  4
  5// Validation helpers in this file are for value-level checks at public API boundaries.
  6//
  7// Add helpers here when they validate a parameter or payload value without
  8// depending on mutable contract state or call flow. Good examples are world
  9// field format, numeric range, CSV payload shape, and page/count limits.
 10//
 11// Do not add helpers here when the assertion depends on store contents,
 12// ownership, permissions, freeze/migration state, uniqueness, or the order of a
 13// specific operation. Keep those assertions close to the domain flow that owns
 14// the state transition.
 15//
 16// As a rule of thumb: validation.gno owns "is this value shaped correctly?";
 17// domain files and stores own "is this action allowed right now?" and
 18// store-owned index invariants.
 19
 20// World field assertions.
 21// Used by CreateWorld and UpdateWorld before constructing or mutating records.
 22func assertWorldID(id uint32) {
 23	if id == 0 {
 24		panic("world id must be positive")
 25	}
 26}
 27
 28func assertBiomeName(biomeName string) {
 29	if len(biomeName) == 0 {
 30		panic("biome name cannot be empty")
 31	}
 32}
 33
 34func assertWorldName(name string) {
 35	if len(name) == 0 {
 36		panic("name cannot be empty")
 37	}
 38	if len(name) > 100 {
 39		panic("name too long (max 100)")
 40	}
 41}
 42
 43func assertWorldSlug(slug string) {
 44	if len(slug) == 0 {
 45		panic("slug cannot be empty")
 46	}
 47
 48	if len(slug) > 50 {
 49		panic("slug too long (max 50)")
 50	}
 51
 52	// Allowed characters: a-z, 0-9, hyphen, underscore
 53	for _, ch := range slug {
 54		if !((ch >= 'a' && ch <= 'z') ||
 55			(ch >= '0' && ch <= '9') ||
 56			ch == '-' || ch == '_') {
 57			panic("slug contains invalid characters (allowed: a-z, 0-9, -, _)")
 58		}
 59	}
 60
 61	// Cannot start or end with hyphen
 62	if slug[0] == '-' || slug[len(slug)-1] == '-' {
 63		panic("slug cannot start or end with hyphen")
 64	}
 65}
 66
 67func mustParseWorldSeed(value string) int {
 68	seed, err := strconv.Atoi(value)
 69	if err != nil {
 70		panic("invalid seed: " + value)
 71	}
 72	assertWorldSeed(seed)
 73	return seed
 74}
 75
 76func assertWorldSeed(seed int) {
 77	if seed <= 0 {
 78		panic("seed must be positive")
 79	}
 80}
 81
 82// Query limit assertions.
 83// Used by public list and batch query entry points.
 84func assertListLimit(field string, count int) {
 85	if count > listLimit {
 86		panic(field + " exceeds listLimit (max: " + strconv.Itoa(listLimit) + ")")
 87	}
 88}
 89
 90func assertListQueryCount(field string, count int) {
 91	if count < 1 {
 92		panic(field + " must be at least 1")
 93	}
 94	assertListLimit(field, count)
 95}
 96
 97func assertListPageCount(page int, count int) {
 98	if page < 1 {
 99		panic("page must be at least 1")
100	}
101	assertListQueryCount("count", count)
102}
103
104func assertBatchLimit(field string, count int) {
105	if count > batchLimit {
106		panic(field + " exceeds batchLimit (max: " + strconv.Itoa(batchLimit) + ")")
107	}
108}
109
110func assertPositiveLimit(limit int) {
111	if limit < 1 {
112		panic("limit must be at least 1")
113	}
114}