// ------------------------------------------------------------------------ // ℹ️ Project active3 // Active Thing (activething.com) git.activething.com/go // // File name fieldsObject.go // ✍️ Created by DEV // 📅 Modified 01/05/2024 // // 🔒 COPYRIGHT Copyright 2024 activething.com // ------------------------------------------------------------------------ // 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 aflds import ( "ablds" "sort" ) type ( // FieldsObject representa un objeto que contiene Fields. Este objeto proporciona métodos para gestionar y // manipular estos campos de diversas formas, como agregar, eliminar, obtener y listar. FieldsObject struct { atts FieldsAtt fields Fields } FieldsObjectFnc func(object *FieldsObject) error ) func NewFieldsObject (options ...FieldsObjectFnc) (*FieldsObject,error) { f := &FieldsObject{} for _,o := range options { if er := o(f); er != nil { return nil,er } } return f,nil } func (f *FieldsObject) Len () int { return len(f.fields) } func (f *FieldsObject) Has (name string) bool { return f.fields.Has(name) } func (f *FieldsObject) Kinds() Kind { return f.fields.Kinds() } func (f *FieldsObject) Get(name string) Field { return f.fields.Get(name) } func (f *FieldsObject) GetAll (name string) []Field { if f.atts.IsNotDuplicate() { f := f.fields.Get(name) if f != nil { return []Field{f} } return nil } return f.fields.GetAll(name) } func (f *FieldsObject) New(name string, value any, kind Kind) error { return f.Add(Create(name,value,kind)) } // Add agrega un nuevo campo al objeto FieldsObject. // Si el objeto está configurado como de solo lectura, // devuelve un error ErrFieldsReadOnly. // Si se especifica que no se permiten campos duplicados y se intenta agregar un // campo que ya existe con el mismo // nombre, devuelve un error ErrDuplicatedField. // Si se especifica que los campos deben ser del mismo tipo y se intenta agregar un campo con un tipo diferente al de // los campos existentes con el mismo nombre, devuelve un error ErrDistinctType. // // Parámetros: // - field: El campo que se va a agregar al objeto FieldsObject. // Devuelve: // - error: Un error, si ocurre alguno; de lo contrario, nil. // // Por motivos de prestaciones es recomendable usar la creación específica de cada // campo que no la creación a través de la factoría con la llamada a New. func (f *FieldsObject) Add(field Field) error { if f.atts.IsReadOnly() { return G.ErrFieldsReadOnly } if p := f.fields.indexOf(field.Name()); p != -1 { if f.atts.IsNotDuplicate() { return G.ErrDuplicatedField } if f.atts.IsSetSameKind() && f.fields[p].Kind() != field.Kind() { return G.ErrDistinctType } } f.fields = f.fields.Add(field) return nil } // Set sustituye o añade un Field al objeto de Fields // Si los atributos del objeto es de solo lectura, devuelve un error ErrFieldsReadOnly. // Si los atributos del objeto no permite defers y se intenta agregar un campo defer, devuelve un error ErrDeferNotAllowed. // Si los atributos del objeto requiere que el Field por el que se sustituye en su caso sean del mismo tipo, si se intenta // agregar un campo de un tipo diferente, devuelve un error ErrDistinctType. // // Parámetros: // - field: El campo que se agregará al objeto de campos. // Devuelve: // - error: Un error, si ocurre alguno; de lo contrario, nil. func (f *FieldsObject) Set(field Field) error { if f.atts.IsReadOnly() { return G.ErrFieldsReadOnly } if f.atts.IsNotDefer() && field.Kind().IsDefer() { return G.ErrDeferNotAllowed } if p := f.fields.indexOf(field.Name()); p != -1 { if f.atts.IsSetSameKind() && field.Kind() != f.fields[p].Kind() { return G.ErrDistinctType } f.fields[p]=field } else { f.fields = f.fields.Add(field) } return nil } func (f *FieldsObject) Del(name string) error { if f.atts.IsReadOnly() { return G.ErrFieldsReadOnly } f.fields = f.fields.Del(name) return nil } // DelAll elimina todos los campos con el nombre especificado del objeto de campos. // Si el objeto de atributos asociado a los campos es de solo lectura, devuelve un error ErrFieldsReadOnly. // Si el nombre proporcionado está vacío, elimina todos los campos del objeto de campos. // // Parámetros: // - name: El nombre del campo que se eliminará. // Devuelve: // - error: Un error, si ocurre alguno; de lo contrario, nil. func (f *FieldsObject) DelAll (name string) error { if f.atts.IsReadOnly() { return G.ErrFieldsReadOnly } if len(name) == 0 { f.fields = f.fields[:0] return nil } if f.atts.IsNotDuplicate() { f.fields = f.fields.Del(name) return nil } f.fields = f.fields.DelAll(name) return nil } func (f *FieldsObject) List() Fields { return f.fields } func (f *FieldsObject) Sort() { if f.atts.IsReadOnly() { return } sort.Sort(f.fields) } func (f *FieldsObject) Build (builder ablds.Builder) { builder.Object(func(ob ablds.ObjectBuilder) { for _,fl := range f.fields { buildFieldAsField(fl,ob) } }) } func FieldsObjectWithAtts (set FieldsAtt) FieldsObjectFnc { return func(f *FieldsObject) error { f.atts = set return nil } } func FieldsObjectWithField(field Field) FieldsObjectFnc { return func(f *FieldsObject) error { return f.Add(field) } } func FieldsObjectWithNew (name string, value any, kind Kind) FieldsObjectFnc { return func(f *FieldsObject) error { return f.New(name,value,kind) } }