The "only allow a single use of an instantiation" is quite easy to do with
present Nim just by disabling `=copy` or `=dup` . You can make all the
procedures that operate on a type take a `sink T` and return `T` then the
following is possible
type MyFile = distinct File
proc `=dup`(_: MyFile): MyFile {.error.}
proc `=destroy`(file: MyFile) =
File(file).close()
proc open(_: typedesc[MyFile], path: string, mode: FileMode): MyFile =
MyFile open(path, mode)
proc write(file: sink MyFile, msg: string): MyFile {.discardable.} =
File(file).write(msg)
move file
proc main() =
var file = MyFile.open("test.txt", fmWrite)
file = file.write("Hello")
file.write(" world!")
main()
Run