github.com/sacloud/iaas-api-go@v1.12.0/internal/dsl/field_desc.go (about)

     1  // Copyright 2022-2023 The sacloud/iaas-api-go Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package dsl
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/sacloud/iaas-api-go/internal/dsl/meta"
    22  )
    23  
    24  // FieldDesc フィールド記述
    25  type FieldDesc struct {
    26  	Name         string
    27  	Tags         *FieldTags
    28  	Type         meta.Type
    29  	Description  string // TODO 現在は未使用
    30  	Methods      []*MethodDesc
    31  	DefaultValue string // デフォルト値、コード生成時にソースコードに直接転記される
    32  }
    33  
    34  // CloneFieldWithTags 指定のフィールドをクローンし指定のタグを設定して返す
    35  func CloneFieldWithTags(f *FieldDesc, tags ...*FieldTags) *FieldDesc {
    36  	var tag *FieldTags
    37  	for _, t := range tags {
    38  		if t != nil {
    39  			tag = t
    40  			break
    41  		}
    42  	}
    43  	if tag == nil {
    44  		tag = &FieldTags{}
    45  	}
    46  	return &FieldDesc{
    47  		Name:         f.Name,
    48  		Tags:         tag,
    49  		Type:         f.Type,
    50  		Description:  f.Description,
    51  		Methods:      f.Methods,
    52  		DefaultValue: f.DefaultValue,
    53  	}
    54  }
    55  
    56  // CloneUpdateFieldWithTags 指定のフィールドのポインタ型をクローンし指定のタグを設定して返す
    57  func CloneUpdateFieldWithTags(f *FieldDesc, tags ...*FieldTags) *FieldDesc {
    58  	return CloneFieldWithTags(f.ToPtrType(), tags...)
    59  }
    60  
    61  // ToPtrType ポインタを受け取る型に変換したFieldDescを返す
    62  func (f *FieldDesc) ToPtrType() *FieldDesc {
    63  	return &FieldDesc{
    64  		Name:         f.Name,
    65  		Tags:         f.Tags,
    66  		Type:         f.Type.ToPtrType(),
    67  		Description:  f.Description,
    68  		Methods:      f.Methods,
    69  		DefaultValue: f.DefaultValue,
    70  	}
    71  }
    72  
    73  // HasTag タグの定義がなされているか
    74  func (f *FieldDesc) HasTag() bool {
    75  	return f.Tags != nil && !f.Tags.Empty()
    76  }
    77  
    78  // SetTags タグの設定
    79  func (f *FieldDesc) SetTags(t *FieldTags) {
    80  	f.Tags = t
    81  }
    82  
    83  // TypeName フィールドの型を返す、コード生成で利用される
    84  func (f *FieldDesc) TypeName() string {
    85  	return f.Type.GoTypeSourceCode()
    86  }
    87  
    88  // TagString タグのソースコード上での表現を返す
    89  func (f *FieldDesc) TagString() string {
    90  	if !f.HasTag() {
    91  		return ""
    92  	}
    93  	return f.Tags.String()
    94  }
    95  
    96  // FieldTags フィールドに付与するタグ
    97  type FieldTags struct {
    98  	// JSON jsonタグ
    99  	JSON string
   100  	// YAML yamlタグ
   101  	YAML string
   102  	// Structs structsタグ
   103  	Structs string
   104  	// MapConv mapconvタグ
   105  	MapConv string
   106  	// Request requestタグ(service向けmapconvタグ)
   107  	Request string
   108  }
   109  
   110  func (f *FieldTags) Empty() bool {
   111  	return f.JSON == "" && f.YAML == "" && f.Structs == "" && f.MapConv == "" && f.Request == ""
   112  }
   113  
   114  // String FieldTagsの文字列表現
   115  func (f *FieldTags) String() string {
   116  	var tags []string
   117  	if f.JSON != "" {
   118  		tags = append(tags, fmt.Sprintf(`json:"%s"`, f.JSON))
   119  	}
   120  	if f.YAML != "" {
   121  		tags = append(tags, fmt.Sprintf(`yaml:"%s"`, f.YAML))
   122  	}
   123  	if f.Structs != "" {
   124  		tags = append(tags, fmt.Sprintf(`structs:"%s"`, f.Structs))
   125  	}
   126  	if f.MapConv != "" {
   127  		tags = append(tags, fmt.Sprintf(`mapconv:"%s"`, f.MapConv))
   128  	}
   129  	if f.Request != "" {
   130  		tags = append(tags, fmt.Sprintf(`request:"%s"`, f.Request))
   131  	}
   132  	return strings.Join(tags, " ")
   133  }
   134  
   135  func RequestOmitEmptyTag() *FieldTags {
   136  	return RequestTag(",omitempty")
   137  }
   138  
   139  func RequestTag(t string, args ...interface{}) *FieldTags {
   140  	tag := t
   141  	if len(args) > 0 {
   142  		tag = fmt.Sprintf(t, args...)
   143  	}
   144  	return &FieldTags{Request: tag}
   145  }