1use oo_bindgen::model::*;
3
4pub const fn get_impl_file() -> &'static str {
6 include_str!("../implementation.rs")
7}
8
9pub fn define(lib: &mut LibraryBuilder, error_type: ErrorTypeHandle) -> BackTraced<()> {
14 let log_level_enum = define_log_level_enum(lib)?;
15
16 let logging_config_struct = define_logging_config_struct(lib, log_level_enum.clone())?;
17
18 let log_callback_interface = lib
19 .define_interface(
20 "logger",
21 "Logging interface that receives the log messages and writes them somewhere.",
22 )?
23 .begin_callback(
24 "on_message",
25 "Called when a log message was received and should be logged",
26 )?
27 .param("level", log_level_enum, "Level of the message")?
28 .param("message", StringType, "Actual formatted message")?
29 .end_callback()?
30 .build_async()?;
31
32 let configure_logging_fn = lib
33 .define_function("configure_logging")?
34 .param(
35 "config",
36 logging_config_struct,
37 "Configuration options for logging"
38 )?
39 .param(
40 "logger",
41 log_callback_interface,
42 "Logger that will receive each logged message",
43 )?
44 .fails_with(error_type)?
45 .doc(
46 doc("Set the callback that will receive all the log messages")
47 .details("There is only a single globally allocated logger. Calling this method a second time will return an error.")
48 .details("If this method is never called, no logging will be performed.")
49 )?
50 .build_static("configure")?;
51
52 let _ = lib
53 .define_static_class("logging")?
54 .static_method(configure_logging_fn)?
55 .doc("Provides a static method for configuring logging")?
56 .build()?;
57
58 Ok(())
59}
60fn define_log_level_enum(lib: &mut LibraryBuilder) -> BackTraced<EnumHandle> {
61 let definition = lib
62 .define_enum("log_level")?
63 .push("error", "Error log level")?
64 .push("warn", "Warning log level")?
65 .push("info", "Information log level")?
66 .push("debug", "Debugging log level")?
67 .push("trace", "Trace log level")?
68 .doc(
69 doc("Log level")
70 .details("Used in {interface:logger.on_message()} callback to identify the log level of a message.")
71 )?
72 .build()?;
73
74 Ok(definition)
75}
76
77fn define_time_format_enum(lib: &mut LibraryBuilder) -> BackTraced<EnumHandle> {
78 let definition = lib
79 .define_enum("time_format")?
80 .push("none", "Don't format the timestamp as part of the message")?
81 .push("rfc_3339", "Format the time using RFC 3339")?
82 .push(
83 "system",
84 "Format the time in a human readable format e.g. 'Jun 25 14:27:12.955'",
85 )?
86 .doc("Describes if and how the time will be formatted in log messages")?
87 .build()?;
88
89 Ok(definition)
90}
91
92fn define_log_output_format_enum(lib: &mut LibraryBuilder) -> BackTraced<EnumHandle> {
93 let definition = lib
94 .define_enum("log_output_format")?
95 .push("text", "A simple text-based format")?
96 .push("json", "Output formatted as JSON")?
97 .doc("Describes how each log event is formatted")?
98 .build()?;
99
100 Ok(definition)
101}
102
103fn define_logging_config_struct(
104 lib: &mut LibraryBuilder,
105 log_level_enum: EnumHandle,
106) -> BackTraced<FunctionArgStructHandle> {
107 let logging_config_struct = lib.declare_function_argument_struct("logging_config")?;
108
109 let log_output_format_enum = define_log_output_format_enum(lib)?;
110 let time_format_enum = define_time_format_enum(lib)?;
111
112 let level = Name::create("level")?;
113 let output_format = Name::create("output_format")?;
114 let time_format = Name::create("time_format")?;
115 let print_level = Name::create("print_level")?;
116 let print_module_info = Name::create("print_module_info")?;
117
118 let logging_config_struct = lib
119 .define_function_argument_struct(logging_config_struct)?
120 .add(&level, log_level_enum, "logging level")?
121 .add(
122 &output_format,
123 log_output_format_enum,
124 "output formatting options",
125 )?
126 .add(&time_format, time_format_enum, "optional time format")?
127 .add(
128 &print_level,
129 Primitive::Bool,
130 "optionally print the log level as part to the message string",
131 )?
132 .add(
133 &print_module_info,
134 Primitive::Bool,
135 "optionally print the underlying Rust module information to the message string",
136 )?
137 .doc("Logging configuration options")?
138 .end_fields()?
139 .begin_initializer(
140 "init",
141 InitializerType::Normal,
142 "Initialize the configuration to default values",
143 )?
144 .default(&level, "info".default_variant())?
145 .default(&output_format, "text".default_variant())?
146 .default(&time_format, "system".default_variant())?
147 .default(&print_level, true)?
148 .default(&print_module_info, false)?
149 .end_initializer()?
150 .build()?;
151
152 Ok(logging_config_struct)
153}