github.com/ipld/go-ipld-prime@v0.21.0/schema/gen/go/mixins/kindTraits.go (about) 1 package mixins 2 3 import ( 4 "io" 5 6 "github.com/ipld/go-ipld-prime/datamodel" 7 ) 8 9 // kindTraitsGenerator is the center of all the other mixins, 10 // and handles all the method generation which is a pure function of the kind. 11 // 12 // OVERRIDE THE METHODS THAT DO APPLY TO YOUR KIND; 13 // the default method bodies produced by this mixin are those that return errors, 14 // and that is not what you want for the methods that *are* interesting for your kind. 15 // The kindTraitsGenerator methods will panic if called for a kind that should've overriden them. 16 // 17 // If you're implementing something that can hold "any" kind, 18 // probably none of these methods apply to you at all. 19 // 20 // The other types in this package use kindTraitsGenerator with a fixed Kind, 21 // and only forward the methods to it that don't apply for their kind; 22 // this means when they're used as an anonymous embed, they grant 23 // all the appropriate dummy methods to their container, 24 // while leaving the ones that are still needed entirely absent, 25 // so the compiler helpfully tells you to finish rather than waiting until 26 // runtime to panic if a should-have-been-overriden method slips through. 27 type kindTraitsGenerator struct { 28 PkgName string 29 TypeName string // as will be printed in messages (e.g. can be goosed up a bit, like "Thing.Repr" instead of "_Thing__Repr"). 30 TypeSymbol string // the identifier in code (sometimes is munged internals like "_Thing__Repr" corresponding to no publicly admitted schema.Type.Name). 31 Kind datamodel.Kind 32 } 33 34 func (g kindTraitsGenerator) emitNodeMethodLookupByString(w io.Writer) { 35 if datamodel.KindSet_JustMap.Contains(g.Kind) { 36 panic("gen internals error: you should've overriden this") 37 } 38 doTemplate(` 39 func ({{ .TypeSymbol }}) LookupByString(string) (datamodel.Node, error) { 40 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupByString("") 41 } 42 `, w, g) 43 } 44 45 func (g kindTraitsGenerator) emitNodeMethodLookupByNode(w io.Writer) { 46 if datamodel.KindSet_JustMap.Contains(g.Kind) { 47 panic("gen internals error: you should've overriden this") 48 } 49 doTemplate(` 50 func ({{ .TypeSymbol }}) LookupByNode(datamodel.Node) (datamodel.Node, error) { 51 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupByNode(nil) 52 } 53 `, w, g) 54 } 55 56 func (g kindTraitsGenerator) emitNodeMethodLookupByIndex(w io.Writer) { 57 if datamodel.KindSet_JustList.Contains(g.Kind) { 58 panic("gen internals error: you should've overriden this") 59 } 60 doTemplate(` 61 func ({{ .TypeSymbol }}) LookupByIndex(idx int64) (datamodel.Node, error) { 62 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupByIndex(0) 63 } 64 `, w, g) 65 } 66 67 func (g kindTraitsGenerator) emitNodeMethodLookupBySegment(w io.Writer) { 68 if datamodel.KindSet_Recursive.Contains(g.Kind) { 69 panic("gen internals error: you should've overriden this") 70 } 71 doTemplate(` 72 func ({{ .TypeSymbol }}) LookupBySegment(seg datamodel.PathSegment) (datamodel.Node, error) { 73 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.LookupBySegment(seg) 74 } 75 `, w, g) 76 } 77 78 func (g kindTraitsGenerator) emitNodeMethodMapIterator(w io.Writer) { 79 if datamodel.KindSet_JustMap.Contains(g.Kind) { 80 panic("gen internals error: you should've overriden this") 81 } 82 doTemplate(` 83 func ({{ .TypeSymbol }}) MapIterator() datamodel.MapIterator { 84 return nil 85 } 86 `, w, g) 87 } 88 89 func (g kindTraitsGenerator) emitNodeMethodListIterator(w io.Writer) { 90 if datamodel.KindSet_JustList.Contains(g.Kind) { 91 panic("gen internals error: you should've overriden this") 92 } 93 doTemplate(` 94 func ({{ .TypeSymbol }}) ListIterator() datamodel.ListIterator { 95 return nil 96 } 97 `, w, g) 98 } 99 100 func (g kindTraitsGenerator) emitNodeMethodLength(w io.Writer) { 101 if datamodel.KindSet_Recursive.Contains(g.Kind) { 102 panic("gen internals error: you should've overriden this") 103 } 104 doTemplate(` 105 func ({{ .TypeSymbol }}) Length() int64 { 106 return -1 107 } 108 `, w, g) 109 } 110 111 func (g kindTraitsGenerator) emitNodeMethodIsAbsent(w io.Writer) { 112 doTemplate(` 113 func ({{ .TypeSymbol }}) IsAbsent() bool { 114 return false 115 } 116 `, w, g) 117 } 118 119 func (g kindTraitsGenerator) emitNodeMethodIsNull(w io.Writer) { 120 doTemplate(` 121 func ({{ .TypeSymbol }}) IsNull() bool { 122 return false 123 } 124 `, w, g) 125 } 126 127 func (g kindTraitsGenerator) emitNodeMethodAsBool(w io.Writer) { 128 if datamodel.KindSet_JustBool.Contains(g.Kind) { 129 panic("gen internals error: you should've overriden this") 130 } 131 doTemplate(` 132 func ({{ .TypeSymbol }}) AsBool() (bool, error) { 133 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsBool() 134 } 135 `, w, g) 136 } 137 138 func (g kindTraitsGenerator) emitNodeMethodAsInt(w io.Writer) { 139 if datamodel.KindSet_JustInt.Contains(g.Kind) { 140 panic("gen internals error: you should've overriden this") 141 } 142 doTemplate(` 143 func ({{ .TypeSymbol }}) AsInt() (int64, error) { 144 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsInt() 145 } 146 `, w, g) 147 } 148 149 func (g kindTraitsGenerator) emitNodeMethodAsFloat(w io.Writer) { 150 if datamodel.KindSet_JustFloat.Contains(g.Kind) { 151 panic("gen internals error: you should've overriden this") 152 } 153 doTemplate(` 154 func ({{ .TypeSymbol }}) AsFloat() (float64, error) { 155 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsFloat() 156 } 157 `, w, g) 158 } 159 160 func (g kindTraitsGenerator) emitNodeMethodAsString(w io.Writer) { 161 if datamodel.KindSet_JustString.Contains(g.Kind) { 162 panic("gen internals error: you should've overriden this") 163 } 164 doTemplate(` 165 func ({{ .TypeSymbol }}) AsString() (string, error) { 166 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsString() 167 } 168 `, w, g) 169 } 170 171 func (g kindTraitsGenerator) emitNodeMethodAsBytes(w io.Writer) { 172 if datamodel.KindSet_JustBytes.Contains(g.Kind) { 173 panic("gen internals error: you should've overriden this") 174 } 175 doTemplate(` 176 func ({{ .TypeSymbol }}) AsBytes() ([]byte, error) { 177 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsBytes() 178 } 179 `, w, g) 180 } 181 182 func (g kindTraitsGenerator) emitNodeMethodAsLink(w io.Writer) { 183 if datamodel.KindSet_JustLink.Contains(g.Kind) { 184 panic("gen internals error: you should've overriden this") 185 } 186 doTemplate(` 187 func ({{ .TypeSymbol }}) AsLink() (datamodel.Link, error) { 188 return mixins.{{ .Kind.String | title }}{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AsLink() 189 } 190 `, w, g) 191 } 192 193 // kindAssemblerTraitsGenerator is an awfully lot like kindTraitsGenerator, 194 // except applying to methods for builders and assemblers. 195 type kindAssemblerTraitsGenerator struct { 196 PkgName string 197 TypeName string // as will be printed in messages (e.g. can be goosed up a bit, like "Thing.Repr" instead of "_Thing__Repr"). 198 AppliedPrefix string // the prefix of what to attach methods to... this one is a little wild: should probably be either "_{{ .Type | TypeSymbol }}__" or "_{{ .Type | TypeSymbol }}__Repr", and we'll just add the words "Builder" and "Assembler". 199 Kind datamodel.Kind 200 } 201 202 // bailed on extracting a common emitNodeBuilderType: too many variations in content and pointer placement to be worth it. 203 // bailed on extracting a common emitNodeBuilderMethods: same. 204 // bailed on extracting a common emitNodeAssemblerType: same. 205 // 206 // If you try to do these, you'll probably need: 207 // - an explicit understanding of if generating representations or not 208 // - to still be ready for boatloads of exceptions if the representation isn't directly castable to and from the type-level node. 209 210 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodBeginMap(w io.Writer) { 211 if datamodel.KindSet_JustMap.Contains(g.Kind) { 212 panic("gen internals error: you should've overriden this") 213 } 214 doTemplate(` 215 func ({{ .AppliedPrefix }}Assembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { 216 return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.BeginMap(0) 217 } 218 `, w, g) 219 } 220 221 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodBeginList(w io.Writer) { 222 if datamodel.KindSet_JustList.Contains(g.Kind) { 223 panic("gen internals error: you should've overriden this") 224 } 225 doTemplate(` 226 func ({{ .AppliedPrefix }}Assembler) BeginList(sizeHint int64) (datamodel.ListAssembler, error) { 227 return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.BeginList(0) 228 } 229 `, w, g) 230 } 231 232 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignNull(w io.Writer) { 233 if datamodel.KindSet_JustNull.Contains(g.Kind) { 234 panic("gen internals error: you should've overriden this") 235 } 236 doTemplate(` 237 func (na *{{ .AppliedPrefix }}Assembler) AssignNull() error { 238 return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignNull() 239 } 240 `, w, g) 241 } 242 243 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignBool(w io.Writer) { 244 if datamodel.KindSet_JustBool.Contains(g.Kind) { 245 panic("gen internals error: you should've overriden this") 246 } 247 doTemplate(` 248 func ({{ .AppliedPrefix }}Assembler) AssignBool(bool) error { 249 return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignBool(false) 250 } 251 `, w, g) 252 } 253 254 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignInt(w io.Writer) { 255 if datamodel.KindSet_JustInt.Contains(g.Kind) { 256 panic("gen internals error: you should've overriden this") 257 } 258 doTemplate(` 259 func ({{ .AppliedPrefix }}Assembler) AssignInt(int64) error { 260 return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignInt(0) 261 } 262 `, w, g) 263 } 264 265 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignFloat(w io.Writer) { 266 if datamodel.KindSet_JustFloat.Contains(g.Kind) { 267 panic("gen internals error: you should've overriden this") 268 } 269 doTemplate(` 270 func ({{ .AppliedPrefix }}Assembler) AssignFloat(float64) error { 271 return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignFloat(0) 272 } 273 `, w, g) 274 } 275 276 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignString(w io.Writer) { 277 if datamodel.KindSet_JustString.Contains(g.Kind) { 278 panic("gen internals error: you should've overriden this") 279 } 280 doTemplate(` 281 func ({{ .AppliedPrefix }}Assembler) AssignString(string) error { 282 return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignString("") 283 } 284 `, w, g) 285 } 286 287 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignBytes(w io.Writer) { 288 if datamodel.KindSet_JustBytes.Contains(g.Kind) { 289 panic("gen internals error: you should've overriden this") 290 } 291 doTemplate(` 292 func ({{ .AppliedPrefix }}Assembler) AssignBytes([]byte) error { 293 return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignBytes(nil) 294 } 295 `, w, g) 296 } 297 298 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodAssignLink(w io.Writer) { 299 if datamodel.KindSet_JustLink.Contains(g.Kind) { 300 panic("gen internals error: you should've overriden this") 301 } 302 doTemplate(` 303 func ({{ .AppliedPrefix }}Assembler) AssignLink(datamodel.Link) error { 304 return mixins.{{ .Kind.String | title }}Assembler{TypeName: "{{ .PkgName }}.{{ .TypeName }}"}.AssignLink(nil) 305 } 306 `, w, g) 307 } 308 309 // bailed on extracting a common emitNodeAssemblerMethodAssignNode: way too many variations. 310 311 func (g kindAssemblerTraitsGenerator) emitNodeAssemblerMethodPrototype(w io.Writer) { 312 doTemplate(` 313 func ({{ .AppliedPrefix }}Assembler) Prototype() datamodel.NodePrototype { 314 return {{ .AppliedPrefix }}Prototype{} 315 } 316 `, w, g) 317 } 318 319 // bailed on extracting a common emitNodeAssemblerOtherBits: it's just self-evident there's nothing common there.