github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/commons/objects/object.go (about)

     1  /*
     2   * Copyright 2023 Wang Min Xiang
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * 	http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   */
    17  
    18  package objects
    19  
    20  import (
    21  	"fmt"
    22  	"github.com/aacfactory/copier"
    23  	"github.com/aacfactory/errors"
    24  )
    25  
    26  func New(src any) Object {
    27  	if src == nil {
    28  		return object{}
    29  	}
    30  	s, ok := src.(Object)
    31  	if ok {
    32  		return s
    33  	}
    34  	return object{
    35  		value: src,
    36  	}
    37  }
    38  
    39  type Object interface {
    40  	Valid() (ok bool)
    41  	Unmarshal(dst any) (err error)
    42  	Value() (v any)
    43  }
    44  
    45  type object struct {
    46  	value any
    47  }
    48  
    49  func (obj object) Valid() (ok bool) {
    50  	if obj.value == nil {
    51  		return
    52  	}
    53  	o, isObject := obj.value.(Object)
    54  	if isObject {
    55  		ok = o.Valid()
    56  		return
    57  	}
    58  	ok = true
    59  	return
    60  }
    61  
    62  func (obj object) Value() (v any) {
    63  	if obj.value == nil {
    64  		return
    65  	}
    66  	o, isObject := obj.value.(Object)
    67  	if isObject {
    68  		v = o.Value()
    69  		return
    70  	}
    71  	v = obj.value
    72  	return
    73  }
    74  
    75  func (obj object) Unmarshal(dst interface{}) (err error) {
    76  	if dst == nil {
    77  		err = errors.Warning("fns: unmarshal object failed").WithCause(fmt.Errorf("dst is nil"))
    78  		return
    79  	}
    80  	if obj.value == nil {
    81  		return
    82  	}
    83  	o, isObject := obj.value.(Object)
    84  	if isObject {
    85  		err = o.Unmarshal(dst)
    86  		return
    87  	}
    88  	// copy
    89  	cpErr := copier.Copy(dst, obj.value)
    90  	if cpErr != nil {
    91  		err = errors.Warning("fns: unmarshal object failed").WithCause(cpErr)
    92  		return
    93  	}
    94  	return
    95  }
    96  
    97  func Value[T any](obj Object) (v T, err error) {
    98  	o, ok := obj.(object)
    99  	if ok {
   100  		v, ok = o.value.(T)
   101  		if ok {
   102  			return
   103  		}
   104  		err = obj.Unmarshal(&v)
   105  		return
   106  	}
   107  	err = obj.Unmarshal(&v)
   108  	return
   109  }