diff --git a/lib/pure/options.nim b/lib/pure/options.nim index b7a6a62128be4..e9e56b399e2af 100644 --- a/lib/pure/options.nim +++ b/lib/pure/options.nim @@ -215,6 +215,34 @@ proc get*[T](self: Option[T], otherwise: T): T {.inline.} = else: otherwise +proc unpack*[T](self: Option[T], val: out T): bool {.inline.} = + ## Unpacks the contents of the `Option` if there are any, and returns true. + ## Otherwise, it simply returns false and sets the value to its default one. + runnableExamples: + var storage: int + + if some(1337).unpack(storage): + assert storage == 1337 + + if not self.isSome: + val = default(T) + false + else: + val = self.get() + true + +template `?=`*[T](x: untyped{ident}, self: Option[T]): bool = + ## Unpacks the contents of the `Option` into a value name provided if there are any, and returns true. + ## Otherwise, returns false and no value is created. + runnableExamples: + let container = some(1337) + + if store ?= container: + assert store == 1337 + + var x: T + unpack(self, x) + proc get*[T](self: var Option[T]): var T {.inline.} = ## Returns the content of the `var Option` mutably. If it has no value, ## an `UnpackDefect` exception is raised. diff --git a/tests/stdlib/toptions.nim b/tests/stdlib/toptions.nim index 63a10e746db7d..c3ca9b97ced98 100644 --- a/tests/stdlib/toptions.nim +++ b/tests/stdlib/toptions.nim @@ -195,6 +195,19 @@ proc main() = let x = none(cstring) doAssert x.isNone doAssert $x == "none(cstring)" + + # Store option's value in a variable, and return a bool + block: + let + x = some(1984) + y = none(int) + + var a, b: int + + doAssert x.unpack(a) + doAssert a == 1984 + + doAssert not y.unpack(b) static: main() main()