github.com/zak-blake/goa@v1.4.1/design/dup.go (about)

     1  package design
     2  
     3  import "github.com/goadesign/goa/dslengine"
     4  
     5  // Dup creates a copy the given data type.
     6  func Dup(d DataType) DataType {
     7  	return newDupper().DupType(d)
     8  }
     9  
    10  // DupAtt creates a copy of the given attribute.
    11  func DupAtt(att *AttributeDefinition) *AttributeDefinition {
    12  	return newDupper().DupAttribute(att)
    13  }
    14  
    15  // dupper implements recursive and cycle safe copy of data types.
    16  type dupper struct {
    17  	dts  map[string]*UserTypeDefinition
    18  	dmts map[string]*MediaTypeDefinition
    19  }
    20  
    21  // newDupper returns a new initialized dupper.
    22  func newDupper() *dupper {
    23  	return &dupper{
    24  		dts:  make(map[string]*UserTypeDefinition),
    25  		dmts: make(map[string]*MediaTypeDefinition),
    26  	}
    27  }
    28  
    29  // DupUserType creates a copy of the given user type.
    30  func (d *dupper) DupUserType(ut *UserTypeDefinition) *UserTypeDefinition {
    31  	return &UserTypeDefinition{
    32  		AttributeDefinition: d.DupAttribute(ut.AttributeDefinition),
    33  		TypeName:            ut.TypeName,
    34  	}
    35  }
    36  
    37  // DupAttribute creates a copy of the given attribute.
    38  func (d *dupper) DupAttribute(att *AttributeDefinition) *AttributeDefinition {
    39  	var valDup *dslengine.ValidationDefinition
    40  	if att.Validation != nil {
    41  		valDup = att.Validation.Dup()
    42  	}
    43  	dup := AttributeDefinition{
    44  		Type:              att.Type,
    45  		Description:       att.Description,
    46  		Validation:        valDup,
    47  		Metadata:          att.Metadata,
    48  		DefaultValue:      att.DefaultValue,
    49  		NonZeroAttributes: att.NonZeroAttributes,
    50  		View:              att.View,
    51  		DSLFunc:           att.DSLFunc,
    52  		Example:           att.Example,
    53  	}
    54  	return &dup
    55  }
    56  
    57  // DupType creates a copy of the given data type.
    58  func (d *dupper) DupType(t DataType) DataType {
    59  	switch actual := t.(type) {
    60  	case Primitive:
    61  		return t
    62  	case *Array:
    63  		return &Array{ElemType: d.DupAttribute(actual.ElemType)}
    64  	case Object:
    65  		res := make(Object, len(actual))
    66  		for n, att := range actual {
    67  			res[n] = d.DupAttribute(att)
    68  		}
    69  		return res
    70  	case *Hash:
    71  		return &Hash{
    72  			KeyType:  d.DupAttribute(actual.KeyType),
    73  			ElemType: d.DupAttribute(actual.ElemType),
    74  		}
    75  	case *UserTypeDefinition:
    76  		if u, ok := d.dts[actual.TypeName]; ok {
    77  			return u
    78  		}
    79  		u := &UserTypeDefinition{
    80  			TypeName: actual.TypeName,
    81  		}
    82  		d.dts[u.TypeName] = u
    83  		u.AttributeDefinition = d.DupAttribute(actual.AttributeDefinition)
    84  		return u
    85  	case *MediaTypeDefinition:
    86  		if m, ok := d.dmts[actual.Identifier]; ok {
    87  			return m
    88  		}
    89  		m := &MediaTypeDefinition{
    90  			Identifier: actual.Identifier,
    91  			Links:      actual.Links,
    92  			Views:      actual.Views,
    93  			Resource:   actual.Resource,
    94  		}
    95  		d.dmts[actual.Identifier] = m
    96  		m.UserTypeDefinition = d.DupUserType(actual.UserTypeDefinition)
    97  		return m
    98  	}
    99  	panic("unknown type " + t.Name())
   100  }