For example, the module securehash is std/sha1 now, but if I didn't want a deprecated warning and I didn't want to import std/sha1 for versions of Nim where it doesn't exist can I know whether or not std/sha1 exists? Something like:
when isModule(std/sha1):
import std/sha1
else:
import securehash
I think none of these work:
when declared(std/sha1): ...
when declared(std/sha1.SecureHash): ...
when declared(std.sha1.SecureHash): ...
when declared(std.sha1): ...
when (compiles do: import std/sha1): ...
Are you sure?
# moduletest.nim
import std/sha1
when (compiles do: import std/sha1):
static: echo "works"
import std/sha1
else:
static: echo "doesn't work"
import securehash
> nim c moduletest
Hint: used config file 'C:\nim-0.18.0\config\nim.cfg' [Conf]
Hint: system [Processing]
Hint: moduletest [Processing]
Hint: sha1 [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
Hint: math [Processing]
Hint: algorithm [Processing]
doesn't work
Hint: securehash [Processing]
moduletest.nim(8, 10) Warning: securehash is deprecated [Deprecated]
when (compiles do: import std/sha1):
Is that still the best option?
And what is about the "do:"? Secret keyword or just a block? And why is block needed?
See https://nim-lang.org/docs/system.html#compiles%2Cuntyped
Still the best option as far as I know, yes.
The do: is a regular block. It is needed because the parser doesn't accept compiles(import std/sha1) as "import" is a statement and not valid in an expression context. You can avoid it via a helper template. See tests/modules/tcanimport.nim for an example.