package jcstypes import ( "path/filepath" "strings" "github.com/samber/lo" ) type JPath struct { comps []string } func (p *JPath) Len() int { return len(p.comps) } func (p *JPath) Comp(idx int) string { return p.comps[idx] } func (p *JPath) Comps() []string { return p.comps } func (p *JPath) LastComp() string { if len(p.comps) == 0 { return "" } return p.comps[len(p.comps)-1] } func (p *JPath) Push(comp string) { p.comps = append(p.comps, comp) } func (p *JPath) Pop() string { if len(p.comps) == 0 { return "" } comp := p.comps[len(p.comps)-1] p.comps = p.comps[:len(p.comps)-1] return comp } func (p *JPath) SplitParent() JPath { if len(p.comps) <= 1 { return JPath{} } parent := JPath{ comps: make([]string, len(p.comps)-1), } copy(parent.comps, p.comps[:len(p.comps)-1]) p.comps = p.comps[len(p.comps)-1:] return parent } func (p *JPath) DropFrontN(cnt int) { if cnt >= len(p.comps) { p.comps = nil return } if cnt <= 0 { return } p.comps = p.comps[cnt:] } func (p *JPath) Concat(other JPath) { p.comps = append(p.comps, other.comps...) } func (p *JPath) ConcatNew(other JPath) JPath { clone := p.Clone() clone.Concat(other) return clone } func (p *JPath) ConcatComps(comps []string) { p.comps = append(p.comps, comps...) } func (p *JPath) ConcatCompsNew(comps ...string) JPath { clone := p.Clone() clone.ConcatComps(comps) return clone } func (p *JPath) Clone() JPath { clone := JPath{ comps: make([]string, len(p.comps)), } copy(clone.comps, p.comps) return clone } func (p *JPath) JoinOSPath() string { return filepath.Join(p.comps...) } func (p JPath) String() string { return strings.Join(p.comps, ObjectPathSeparator) } func (p JPath) ToString() (string, error) { return p.String(), nil } func (p JPath) FromString(s string) (any, error) { p2 := PathFromJcsPathString(s) return p2, nil } func (p JPath) MarshalJSON() ([]byte, error) { return []byte(`"` + p.String() + `"`), nil } func (p *JPath) UnmarshalJSON(data []byte) error { s := string(data) s = strings.Trim(s, `"`) p2 := PathFromJcsPathString(s) *p = p2 return nil } func PathFromComps(comps ...string) JPath { c2 := make([]string, len(comps)) copy(c2, comps) return JPath{ comps: c2, } } func PathFromOSPathString(s string) JPath { cleaned := filepath.Clean(s) comps := strings.Split(cleaned, string(filepath.Separator)) return JPath{ comps: lo.Reject(comps, func(s string, idx int) bool { return s == "" }), } } func PathFromJcsPathString(s string) JPath { comps := strings.Split(s, ObjectPathSeparator) i := 0 for ; i < len(comps) && len(comps[i]) == 0; i++ { } comps = comps[i:] return JPath{ comps: comps, } }