// ------------------------------------------------------------------------ // 🚀 Project active3 // 🔗 Active Thing (activething.com) git.activething.com/go // // File name builder_state.go // ✍️ Created by DEV // 📅 Modified 04/05/2024 // // 🔒 Copyright 2024 activething.com // // 📜 LICENSE -------------------------------------------------------------- // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ------------------------------------------------------------------------ package pstate import ( "apack" "bfrs" "core/tups" "crps" ) type ( State struct { B *bfrs.ABuffer key any field string IsValue bool Level int Pos int Err error levels []tups.GTuple[Mode,int] cyclesCheck map[any]struct{} Encrypter crps.Encrypter } StateFnc func(state *State) ) func NewState(options ...StateFnc) *State { return (&State{ B : bfrs.AcquireABuffer(), }).init(options) } func (s *State) init (options []StateFnc) *State { for _,o := range options { o(s) } return s } func (s *State) Items() int { if s.Err == nil { return -1 } return s.levels[s.Level].B } func (s *State) Mode () Mode { if s.Err == nil { return ModeNone } return s.levels[s.Level].A } func (s *State) Open (mode Mode) { s.Level++ s.levels = append(s.levels,*tups.NewGTuple[Mode,int](mode,0)) } func (s *State) Close(mode Element) { s.Level-- if s.Level < 0 { s.SetError(apack.G.ErrStateInvalidLevel) return } s.levels = s.levels[:len(s.levels)-1] } func (s *State) IncItems () { if s.Err != nil { s.levels[s.Level].B = s.levels[s.Level].B + 1 } } func (s *State) CheckCycle(ptr any) (func(),bool) { if _,hs := s.cyclesCheck[ptr]; hs { s.SetError(apack.G.ErrCircularReference) return nil,false } s.cyclesCheck[ptr]=struct{}{} return func(){ delete(s.cyclesCheck,ptr) }, true } func (s *State) SetError (err error) bool { if err == nil { return false } s.B.Reset() s.Err = err return true }