// ------------------------------------------------------------------------ // 🚀 Project active3 // 🔗 Active Thing (activething.com) git.activething.com/go // // File name stringify.go // ✍️ Created by DEV // 📅 Modified 06/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 erstr import ( "bytes" "fmt" "strings" "typs/strs" ) type ( StringifyError struct { labelSep string lineLabelFmt string lineErrorFmt string trans strs.Transformers } StringifyErrorFnc func (stringify *StringifyError) ) func NewStringifyError (options ...StringifyErrorFnc) *StringifyError { s := &StringifyError{ labelSep: labelSep, lineLabelFmt: "%s" + labelSep + "%s\n", lineErrorFmt: labelError + labelSep + "%s\n", } for _,o := range options { o(s) } return s } func (s *StringifyError) Stringify (text string, err error) string { ln := []string { "", text } var nl string ne := err for ne != nil { if st,is := ne.(stringer); is { nl = st.String() } if uw,is := ne.(unwrapper); is { ne = uw.Unwrap() } else { ne = nil if strings.Index(nl,labelError) != -1 { ln[0]= s.trans.Transform(nl) break } } ln = append(ln, s.trans.Transform(nl)) } if len(ln[0]) == 0 { ln[0]=s.trans.Transform(err.Error()) } if len(ln) == 0 { return ln[0] } b := bytes.Buffer{} for _,l := range ln { b.WriteString(l) } return b.String() } func (s *StringifyError) FormatLineError(strErr string) string { return fmt.Sprintf(s.lineErrorFmt,strErr) } func (s *StringifyError) FormatLine (label, text string) string { return fmt.Sprintf(s.lineLabelFmt,label,text) } func (s *StringifyError) removeLabel (text string) string { if strings.Index(text,s.labelSep) == -1 { return text } l := strings.Split(text,"\n") b := bytes.Buffer{} for _,t := range l { if p := strings.Index(t,s.labelSep); p != -1 { b.WriteString(t[p+len(s.labelSep):]) b.WriteByte('\n') } else { b.WriteString(t) } } return b.String() } func WithFormats (fmtLabelLn, fmtErrorLn, sep string) StringifyErrorFnc { return func (s *StringifyError) { s.labelSep = sep s.lineLabelFmt = fmtLabelLn s.lineErrorFmt = fmtErrorLn } } func WithTransformers (add bool, transformers ...any) StringifyErrorFnc { return func (s *StringifyError) { if !add { s.trans = s.trans[:0] } for _, tf := range transformers { switch t:=tf.(type) { case string: if t == LabelRemover { s.trans = append(s.trans,strs.TransformFnc(s.removeLabel)) } else { tr, hs := strs.G.Transformers.Get(t) if !hs { panic(strs.G.ErrTransformerNotFound) } s.trans = append(s.trans, tr) } case strs.Transformer: if t != nil { s.trans = append(s.trans,t) } case func(string)string: if t != nil { s.trans = append(s.trans,strs.TransformFnc(t)) } default: panic(strs.G.ErrTransformerNotFound) } } } }