"""
ImplementIEnumerable2.cobra

This version implements a generic file cabinet: You can give it any type of
object to hold.


See also: ImplementIEnumerable1.cobra
"""


class FileCabinet<of T> implements IEnumerable<of T>

	get records from var = List<of T>()

	get nextSerialNum as int
		return _records.count + 1

	def getEnumerator as IEnumerator<of T>
		return _records.getEnumerator

	def getEnumerator as System.Collections.IEnumerator
		implements System.Collections.IEnumerable
		return .getEnumerator


class Record

	cue init(serialNum as int, name as String)
		base.init
		_serialNum, _name = serialNum, name

	pro serialNum from var as int

	pro name from var as String

	def toString as String is override
		return '[.typeOf.name]([_serialNum], [_name])'


class Program

	def main is shared
		# build a cabinet:
		cabinet = FileCabinet<of Record>()
		cabinet.records.add(Record(cabinet.nextSerialNum, 'Red'))
		cabinet.records.add(Record(cabinet.nextSerialNum, 'Green'))
		cabinet.records.add(Record(cabinet.nextSerialNum, 'Blue'))

		# because cabinet is an IEnumerable, it can be for'ed:
		for r2 in cabinet
			print r2

		# and passed to a List initializer:
		records = List<of Record>(cabinet)
		for r3 in records
			assert r3.serialNum > 0
