@@ -531,16 +531,25 @@ func (s *Spec) nextTypeID() (TypeID, error) {
531
531
// Returns an error wrapping ErrNotFound if a Type with the given ID
532
532
// does not exist in the Spec.
533
533
func (s * Spec ) TypeByID (id TypeID ) (Type , error ) {
534
- if id < s .firstTypeID {
534
+ typ , ok := s .typeByID (id )
535
+ if ! ok {
535
536
return nil , fmt .Errorf ("look up type with ID %d (first ID is %d): %w" , id , s .firstTypeID , ErrNotFound )
536
537
}
537
538
539
+ return typ , nil
540
+ }
541
+
542
+ func (s * Spec ) typeByID (id TypeID ) (Type , bool ) {
543
+ if id < s .firstTypeID {
544
+ return nil , false
545
+ }
546
+
538
547
index := int (id - s .firstTypeID )
539
548
if index >= len (s .types ) {
540
- return nil , fmt . Errorf ( "look up type with ID %d: %w" , id , ErrNotFound )
549
+ return nil , false
541
550
}
542
551
543
- return s .types [index ], nil
552
+ return s .types [index ], true
544
553
}
545
554
546
555
// TypeID returns the ID for a given Type.
@@ -671,26 +680,27 @@ func LoadSplitSpecFromReader(r io.ReaderAt, base *Spec) (*Spec, error) {
671
680
672
681
// TypesIterator iterates over types of a given spec.
673
682
type TypesIterator struct {
674
- types []Type
675
- index int
683
+ spec * Spec
684
+ id TypeID
685
+ done bool
676
686
// The last visited type in the spec.
677
687
Type Type
678
688
}
679
689
680
690
// Iterate returns the types iterator.
681
691
func (s * Spec ) Iterate () * TypesIterator {
682
- // We share the backing array of types with the Spec. This is safe since
683
- // we don't allow deletion or shuffling of types.
684
- return & TypesIterator {types : s .types , index : 0 }
692
+ return & TypesIterator {spec : s , id : s .firstTypeID }
685
693
}
686
694
687
695
// Next returns true as long as there are any remaining types.
688
696
func (iter * TypesIterator ) Next () bool {
689
- if len ( iter .types ) <= iter . index {
697
+ if iter .done {
690
698
return false
691
699
}
692
700
693
- iter .Type = iter .types [iter .index ]
694
- iter .index ++
695
- return true
701
+ var ok bool
702
+ iter .Type , ok = iter .spec .typeByID (iter .id )
703
+ iter .id ++
704
+ iter .done = ! ok
705
+ return ! iter .done
696
706
}
0 commit comments