-module(future). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -define(FILEPATH, "src\\future.gleam"). -export([new/2, from_result/1, from_failure/1, then/2, is_complete/1, status/1, release/1, add_failure_handler/2, wait/1, auto_release/1, 'after'/2]). -export_type([future/3, status/2]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type future(DTU, DTV, DTW) :: any() | {gleam_phantom, DTU, DTV, DTW}. -type status(DTX, DTY) :: {completed, {ok, DTX} | {error, DTY}} | running | {failed, binary()} | released. -file("src\\future.gleam", 29). ?DOC( " Creates a future from an executable\n" " \n" " > Please note that lifecycle management of this future is managed by YOU!\n" " > You MUST release it when you are done with it else have a memory leak! (This comes from how the erlang gc works)\n" " > If you want to immediately release the future on completion then use `auto_release`!\n" ). -spec new(fun((DUI) -> {ok, DUJ} | {error, DUK}), DUI) -> future(DUI, DUJ, DUK). new(Executable, Starting_value) -> 'futureFfi':start(Executable, Starting_value). -file("src\\future.gleam", 41). ?DOC( " Creates a future from a result\n" " \n" " This future will never have the status of running or failed\n" " \n" " > Just as with `new` you own the lifecycle of this future and must release it when you are done with it\n" ). -spec from_result({ok, DUR} | {error, DUS}) -> future(any(), DUR, DUS). from_result(Result) -> 'futureFfi':start(Result). -file("src\\future.gleam", 50). -spec from_failure(binary()) -> future(any(), any(), any()). from_failure(Reason) -> 'futureFfi':start({failed, Reason}). -file("src\\future.gleam", 66). ?DOC( " Chains a future with another future\n" " \n" " If the first future fails, all chained futures will fail with the same reason with a prefix of \"Prior future failed: \"\n" " \n" " If the first future is released BEFORE calling then, the second future will fail with the reason \"Prior future was released before initialisation\"\n" " If the first future is released AFTER calling then, the second future will operate as expected and still recieve the result of the first future\n" ). -spec then( future(any(), DVO, DVP), fun(({ok, DVO} | {error, DVP}) -> {ok, DVV} | {error, DVW}) ) -> future({ok, DVO} | {error, DVP}, DVV, DVW). then(Future, Next) -> 'futureFfi':start(Future, Next). -file("src\\future.gleam", 74). ?DOC(" If the future has completed, IE a result is available or failed or was released\n"). -spec is_complete(future(any(), any(), any())) -> boolean(). is_complete(Future) -> 'futureFfi':is_complete(Future). -file("src\\future.gleam", 91). ?DOC(" Returns the status of the future\n"). -spec status(future(any(), DWM, DWN)) -> status(DWM, DWN). status(Future) -> 'futureFfi':status(Future). -file("src\\future.gleam", 101). ?DOC( " Releases the future, allowing it to be garbage collected\n" " \n" " If the future is still running only the storage for the state will be released, the execution will continue and result will still be made available for chained futures\n" " If the future has completed it will be marked for garbage collection and the state will be made unavailable\n" " \n" " You should assume that any future not released will never be garbage collected\n" ). -spec release(future(any(), any(), any())) -> nil. release(Future) -> 'futureFfi':release(Future). -file("src\\future.gleam", 112). ?DOC( " Adds a handler to the future that will be called if the future fails\n" " \n" " The handler will be called with the reason for the failure\n" " \n" " If the future is released (before or after) this will do nothing\n" " \n" " This handler does not have to be released as it's lifecycle is self contained\n" ). -spec add_failure_handler(future(DWZ, DXA, DXB), fun((binary()) -> nil)) -> future(DWZ, DXA, DXB). add_failure_handler(Future, Handler) -> 'futureFfi':create_failure_handler(Future, Handler). -file("src\\future.gleam", 124). ?DOC( " Blocks execution until the future is complete\n" " \n" " If the future is already complete this will return immediately\n" " \n" " > This function is only available in the erlang target!\n" ). -spec wait(future(any(), any(), any())) -> nil. wait(Future) -> 'futureFfi':wait(Future). -file("src\\future.gleam", 172). ?DOC( " Automatically releases the future when it's complete\n" " \n" " The future returned is the one provided! You no longer need to call `release` on it (but doing so will do nothing)\n" ). -spec auto_release(future(DYA, DYB, DYC)) -> future(DYA, DYB, DYC). auto_release(Future) -> 'futureFfi':auto_release(Future). -file("src\\future.gleam", 133). ?DOC( " Registers the given exectuable to be invoked once the future is complete\n" " \n" " This just registers:\n" " - A new future via `then`\n" " - A handler via `add_failure_handler`\n" ). -spec 'after'(future(DXO, DXP, DXQ), fun((status(DXP, DXQ)) -> any())) -> future(DXO, DXP, DXQ). 'after'(Future, Executable) -> 'futureFfi':once_complete(Future, Executable).