// Package core - core types like ID and Path. package core import ( "errors" "regexp" "strings" ) var ErrNotFound = errors.New("not found") type Page[T any] struct { Items []T Cursor string } type PageReq struct { Limit int Cursor string } type Path string var pathSegment = regexp.MustCompile(`^[a-zA-Z0-9_]+$`) func (p Path) Valid() error { s := string(p) if s == "" { return errors.New("path is empty") } segments := strings.Split(s, ".") for _, seg := range segments { if seg == "" { return errors.New("path contains empty segment") } if !pathSegment.MatchString(seg) { return errors.New("path segment must match [a-zA-Z0-9_]+: " + seg) } } return nil } // Contains reports whether p equals or is an ancestor of other. // An empty path contains nothing. func (p Path) Contains(other Path) bool { if p == "" { return true } if other == "" { return false } return p == other || strings.HasPrefix(string(other), string(p)+".") } func (p Path) Parent() Path { s := string(p) i := strings.LastIndex(s, ".") if i < 0 { return "" } return Path(s[:i]) } // Root returns the first segment of the path, or "" if empty. func (p Path) Root() string { s := string(p) if i := strings.Index(s, "."); i >= 0 { return s[:i] } return s } // Segments returns all path segments. func (p Path) Segments() []string { if p == "" { return nil } return strings.Split(string(p), ".") }