3
0

Introduce .Clone to typed values for deep copy

This commit is contained in:
Tomaž Jerman 2024-01-31 14:12:37 +01:00
parent 01aaddad58
commit 52ac5698c8
5 changed files with 250 additions and 0 deletions

View File

@ -54,3 +54,8 @@ func ReadRequestBody(in interface{}) (s string) {
return string(b)
}
func (t *EmailMessage) Clone() (expr.TypedValue, error) {
msg := *t.value.msg
return NewEmailMessage(&msg)
}

View File

@ -662,3 +662,42 @@ func (t *ComposeRecordValues) Delete(keys ...string) (out expr.TypedValue, err e
return rv, nil
}
func (v *Attachment) Clone() (expr.TypedValue, error) {
att := *v.value
aux, err := NewAttachment(&att)
return aux, err
}
func (v *ComposeModule) Clone() (expr.TypedValue, error) {
aux, err := NewComposeModule(v.value.Clone())
return aux, err
}
func (v *ComposeNamespace) Clone() (expr.TypedValue, error) {
aux, err := NewComposeNamespace(v.value.Clone())
return aux, err
}
func (v *ComposeRecord) Clone() (expr.TypedValue, error) {
aux, err := NewComposeRecord(v.value.Clone())
return aux, err
}
func (v *ComposeRecordValues) Clone() (expr.TypedValue, error) {
aux, err := NewComposeRecordValues(v.value.Clone())
return aux, err
}
func (v *ComposeRecordValueErrorSet) Clone() (expr.TypedValue, error) {
errs := types.RecordValueErrorSet{
Set: make([]types.RecordValueError, len(v.value.Set)),
}
for i, v := range v.value.Set {
errs.Set[i] = v
}
aux, err := NewComposeRecordValueErrorSet(&errs)
return aux, err
}

View File

@ -48,6 +48,28 @@ func KvFunctions() []gval.Language {
}
}
func (v *Vars) Clone() (out TypedValue, err error) {
if v == nil || len(v.value) == 0 {
return EmptyVars(), nil
}
aux := &Vars{
value: make(map[string]TypedValue, len(v.value)),
}
// Can run concurrently
for k, v := range v.value {
x, err := v.Clone()
if err != nil {
return nil, err
}
aux.value[k] = x
}
return aux, nil
}
func EmptyKV() *KV {
return &KV{value: make(map[string]string)}
}
@ -872,3 +894,135 @@ func (t *KVV) Delete(keys ...string) (out TypedValue, err error) {
return kvv, nil
}
func (v *Any) Clone() (out TypedValue, err error) {
aux, err := NewAny(v.GetValue())
return aux, err
}
func (v *Array) Clone() (out TypedValue, err error) {
aux := &Array{
value: make([]TypedValue, len(v.value)),
}
// Can run concurrently
for i, v := range v.value {
x, err := v.Clone()
if err != nil {
return nil, err
}
aux.value[i] = x
}
return aux, nil
}
func (v *Boolean) Clone() (out TypedValue, err error) {
aux, err := NewBoolean(v.GetValue())
return aux, err
}
func (v *Bytes) Clone() (out TypedValue, err error) {
cpy := make([]byte, len(v.value))
copy(cpy, v.value)
aux, err := NewBytes(cpy)
return aux, err
}
func (v *DateTime) Clone() (out TypedValue, err error) {
t := *v.GetValue()
aux, err := NewDateTime(&t)
return aux, err
}
func (v *Duration) Clone() (out TypedValue, err error) {
aux, err := NewDuration(v.GetValue())
return aux, err
}
func (v *Float) Clone() (out TypedValue, err error) {
aux, err := NewFloat(v.GetValue())
return aux, err
}
func (v *ID) Clone() (out TypedValue, err error) {
aux, err := NewID(v.GetValue())
return aux, err
}
func (v *Integer) Clone() (out TypedValue, err error) {
aux, err := NewInteger(v.GetValue())
return aux, err
}
func (v *KV) Clone() (out TypedValue, err error) {
aux := &KV{
value: make(map[string]string, len(v.value)),
}
// Can run concurrently
for k, v := range v.value {
aux.value[k] = v
}
return aux, nil
}
func (v *KVV) Clone() (out TypedValue, err error) {
aux := &KVV{
value: make(map[string][]string, len(v.value)),
}
// Can run concurrently
for k, vv := range v.value {
aux.value[k] = make([]string, len(vv))
copy(aux.value[k], vv)
}
return aux, nil
}
func (v *Handle) Clone() (out TypedValue, err error) {
aux, err := NewHandle(v.GetValue())
return aux, err
}
func (v *HttpRequest) Clone() (out TypedValue, err error) {
aux, err := NewHttpRequest(v.GetValue())
return aux, err
}
func (v *Reader) Clone() (out TypedValue, err error) {
aux, err := NewReader(v.GetValue())
return aux, err
}
func (v *String) Clone() (out TypedValue, err error) {
aux, err := NewString(v.GetValue())
return aux, err
}
func (v *Url) Clone() (out TypedValue, err error) {
u := *v.GetValue()
aux, err := NewUrl(&u)
return aux, err
}
func (v *Meta) Clone() (out TypedValue, err error) {
m := make(map[string]any, len(v.value))
for k, v := range v.value {
m[k] = v
}
aux, err := NewMeta(v.GetValue())
return aux, err
}
func (v *UnsignedInteger) Clone() (out TypedValue, err error) {
aux, err := NewUnsignedInteger(v.GetValue())
return aux, err
}
func (v Unresolved) Clone() (out TypedValue, err error) {
return nil, fmt.Errorf("cannot unref unresolved type")
}

View File

@ -13,6 +13,7 @@ type (
TypedValue interface {
Type
Assigner
Clone() (TypedValue, error)
Get() interface{}
}

View File

@ -208,3 +208,54 @@ func CastToAction(val interface{}) (out *actionlog.Action, err error) {
return nil, fmt.Errorf("unable to cast type %T to %T", val, out)
}
}
func (v *Action) Clone() (expr.TypedValue, error) {
aux := *v.value
return NewAction(&aux)
}
func (v *DocumentType) Clone() (expr.TypedValue, error) {
return NewDocumentType(v.value)
}
func (v *QueueMessage) Clone() (expr.TypedValue, error) {
aux := *v.value
return NewQueueMessage(&aux)
}
func (v *RbacResource) Clone() (expr.TypedValue, error) {
return NewRbacResource(v.value)
}
func (v *RenderOptions) Clone() (expr.TypedValue, error) {
aux := make(map[string]string)
for k, v := range v.value {
aux[k] = v
}
return NewRenderOptions(aux)
}
func (v *RenderedDocument) Clone() (expr.TypedValue, error) {
aux := *v.value
return NewRenderedDocument(&aux)
}
func (v *Role) Clone() (expr.TypedValue, error) {
aux := v.value.Clone()
return NewRole(&aux)
}
func (v *Template) Clone() (expr.TypedValue, error) {
aux := v.value.Clone()
return NewTemplate(&aux)
}
func (v *TemplateMeta) Clone() (expr.TypedValue, error) {
return NewTemplateMeta(v.value)
}
func (v *User) Clone() (expr.TypedValue, error) {
aux := v.value.Clone()
return NewUser(&aux)
}