diff --git a/src/utils.jl b/src/utils.jl index 5c8f39e..7e2dc0e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -66,9 +66,18 @@ function emit_message( f::Function, level::Nothing, file, line, _module) end +function get_message_level(verb::AbstractVerbositySpecifier, option) + return logging_message_level(getproperty(verb, option)) +end + +function get_message_level(verb::Bool, _) + return verb ? logging_message_level(WarnLevel()) : logging_message_level(Silent()) +end + """ - `@SciMLMessage(message, verbosity, option)` + `@SciMLMessage(message, verbosity::AbstracVerbositySpecifier, option::Symbol)` + `@SciMLMessage(message, verbosity::Bool)` A macro that emits a log message based on the log level specified in the `option` of the `AbstractVerbositySpecifier` supplied. @@ -114,21 +123,40 @@ function solve_problem(problem; verbose = SolverVerbosity(Standard())) return result end ``` + +Alternatively, the macro also accepts a boolean value for `verb`: + +When `verb` is a boolean: +- `true` will emit the message at `WarnLevel()` +- `false` will suppress the message (equivalent to `Silent()`) + +The two-argument form `@SciMLMessage(message, verbosity)` can be used when `verbosity` is a `Bool`: + +```julia +function solve_problem(problem; verbose::Bool = true) + @SciMLMessage("Starting solver", verbose) + # ... solver logic ... +end +``` """ macro SciMLMessage(f_or_message, verb, option) line = __source__.line file = string(__source__.file) _module = __module__ - expr = quote + expr = quote emit_message($(esc(f_or_message)), - logging_message_level(getproperty($(esc(verb)), $(esc(option)))), + get_message_level($(esc(verb)), $(esc(option))), $file, $line, $_module) - end + end return expr end +macro SciMLMessage(f_or_message, verb) + return esc(:(@SciMLMessage($f_or_message, $verb, :_))) +end + """ `verbosity_to_int(verb::AbstractMessageLevel)` diff --git a/test/basics.jl b/test/basics.jl index 73c1573..188db73 100644 --- a/test/basics.jl +++ b/test/basics.jl @@ -125,4 +125,46 @@ end "Outer result: $counter" end end +end + +@testset "Boolean verbosity" begin + # Test with true - should emit at WarnLevel (three-arg form) + @test_logs (:warn, "Message with verbose=true") @SciMLMessage("Message with verbose=true", true, :ignored) + + # Test with false - should not emit anything (three-arg form) + @test_logs min_level = Logging.Debug @SciMLMessage("Message with verbose=false", false, :ignored) + + # Test with function form and true (three-arg form) + @test_logs (:warn, "Computed message: 42") @SciMLMessage(true, :ignored) do + x = 40 + 2 + "Computed message: $x" + end + + # Test with function form and false - should not compute or emit (three-arg form) + computation_ran = false + @test_logs min_level = Logging.Debug @SciMLMessage(false, :ignored) do + computation_ran = true + "This should not be computed" + end + @test !computation_ran # Verify function was never called when verbose=false + + # Test two-argument form with true + @test_logs (:warn, "Two-arg form with true") @SciMLMessage("Two-arg form with true", true) + + # Test two-argument form with false + @test_logs min_level = Logging.Debug @SciMLMessage("Two-arg form with false", false) + + # Test two-argument form with function and true + @test_logs (:warn, "Two-arg computed: 100") @SciMLMessage(true) do + y = 50 * 2 + "Two-arg computed: $y" + end + + # Test two-argument form with function and false + computation_ran_2arg = false + @test_logs min_level = Logging.Debug @SciMLMessage(false) do + computation_ran_2arg = true + "This should not be computed either" + end + @test !computation_ran_2arg # Verify function was never called when verbose=false end \ No newline at end of file