// ------------------------------------------------------------------------ // 🚀 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" "crps" ) type ( State struct { B *bfrs.ABuffer key any field string Mode Mode Element Element IsValue bool Level int Pos int Err error levelsItem []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.levelsItem[s.Level] } func (s *State) Open (element Element) { s.Level++ s.levelsItem = append(s.levelsItem,0) } func (s *State) Close(element Element) { s.Level-- if s.Level < 0 { s.SetError(apack.G.ErrStateInvalidLevel) return } s.levelsItem = s.levelsItem[:len(s.levelsItem)-1] } func (s *State) IncItems () { if s.Err != nil { s.levelsItem[s.Level]++ } } 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 }