From 25a6a973d2177144277435499c21b7427dba1856 Mon Sep 17 00:00:00 2001 From: Nanaloveyuki Date: Wed, 20 May 2026 11:37:49 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Update=20More=20API=20Document?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent1.md | 5 -- agent2.md | 5 -- agent3.md | 5 -- docs/api/buffered-sink.md | 66 ++++++++++++++++ docs/api/build-application-async-logger.md | 71 +++++++++++++++++ docs/api/build-application-logger.md | 66 ++++++++++++++++ .../build-application-text-async-logger.md | 71 +++++++++++++++++ docs/api/build-async-text-logger.md | 69 +++++++++++++++++ docs/api/build-library-async-logger.md | 71 +++++++++++++++++ docs/api/build-library-async-text-logger.md | 71 +++++++++++++++++ docs/api/build-library-logger.md | 66 ++++++++++++++++ docs/api/callback-sink.md | 69 +++++++++++++++++ docs/api/color-mode-label.md | 64 ++++++++++++++++ docs/api/color-support-label.md | 64 ++++++++++++++++ docs/api/console-sink.md | 61 +++++++++++++++ docs/api/default-library-logger.md | 63 +++++++++++++++ docs/api/default-logger-config.md | 60 +++++++++++++++ docs/api/default-sink-config.md | 60 +++++++++++++++ docs/api/default-style-tag-registry.md | 60 +++++++++++++++ docs/api/default-text-formatter-config.md | 60 +++++++++++++++ docs/api/fanout-sink.md | 68 +++++++++++++++++ docs/api/filter-sink.md | 67 ++++++++++++++++ docs/api/global-style-tag-registry.md | 62 +++++++++++++++ docs/api/index.md | 40 ++++++++++ docs/api/json-console-sink.md | 61 +++++++++++++++ ...arse-and-build-application-async-logger.md | 68 +++++++++++++++++ .../api/parse-and-build-application-logger.md | 68 +++++++++++++++++ .../parse-and-build-library-async-logger.md | 68 +++++++++++++++++ docs/api/parse-and-build-library-logger.md | 68 +++++++++++++++++ docs/api/parse-async-logger-config-text.md | 66 ++++++++++++++++ docs/api/patch-sink.md | 66 ++++++++++++++++ docs/api/queued-sink.md | 71 +++++++++++++++++ docs/api/reset-global-style-tag-registry.md | 57 ++++++++++++++ docs/api/set-global-style-tag-registry.md | 62 +++++++++++++++ docs/api/split-by-level.md | 72 ++++++++++++++++++ docs/api/split-sink.md | 68 +++++++++++++++++ docs/api/style-markup-mode-label.md | 64 ++++++++++++++++ docs/api/style-tag-registry.md | 60 +++++++++++++++ docs/api/text-callback-sink.md | 73 ++++++++++++++++++ docs/api/text-console-sink.md | 67 ++++++++++++++++ docs/api/text-style.md | 76 +++++++++++++++++++ 41 files changed, 2484 insertions(+), 15 deletions(-) delete mode 100644 agent1.md delete mode 100644 agent2.md delete mode 100644 agent3.md create mode 100644 docs/api/buffered-sink.md create mode 100644 docs/api/build-application-async-logger.md create mode 100644 docs/api/build-application-logger.md create mode 100644 docs/api/build-application-text-async-logger.md create mode 100644 docs/api/build-async-text-logger.md create mode 100644 docs/api/build-library-async-logger.md create mode 100644 docs/api/build-library-async-text-logger.md create mode 100644 docs/api/build-library-logger.md create mode 100644 docs/api/callback-sink.md create mode 100644 docs/api/color-mode-label.md create mode 100644 docs/api/color-support-label.md create mode 100644 docs/api/console-sink.md create mode 100644 docs/api/default-library-logger.md create mode 100644 docs/api/default-logger-config.md create mode 100644 docs/api/default-sink-config.md create mode 100644 docs/api/default-style-tag-registry.md create mode 100644 docs/api/default-text-formatter-config.md create mode 100644 docs/api/fanout-sink.md create mode 100644 docs/api/filter-sink.md create mode 100644 docs/api/global-style-tag-registry.md create mode 100644 docs/api/json-console-sink.md create mode 100644 docs/api/parse-and-build-application-async-logger.md create mode 100644 docs/api/parse-and-build-application-logger.md create mode 100644 docs/api/parse-and-build-library-async-logger.md create mode 100644 docs/api/parse-and-build-library-logger.md create mode 100644 docs/api/parse-async-logger-config-text.md create mode 100644 docs/api/patch-sink.md create mode 100644 docs/api/queued-sink.md create mode 100644 docs/api/reset-global-style-tag-registry.md create mode 100644 docs/api/set-global-style-tag-registry.md create mode 100644 docs/api/split-by-level.md create mode 100644 docs/api/split-sink.md create mode 100644 docs/api/style-markup-mode-label.md create mode 100644 docs/api/style-tag-registry.md create mode 100644 docs/api/text-callback-sink.md create mode 100644 docs/api/text-console-sink.md create mode 100644 docs/api/text-style.md diff --git a/agent1.md b/agent1.md deleted file mode 100644 index 3c65448..0000000 --- a/agent1.md +++ /dev/null @@ -1,5 +0,0 @@ -# Agent 1 - -This file is reserved for Agent 1 prompts and handoff summaries. - -Overwrite this file in future multi-agent rounds. diff --git a/agent2.md b/agent2.md deleted file mode 100644 index 6b311a6..0000000 --- a/agent2.md +++ /dev/null @@ -1,5 +0,0 @@ -# Agent 2 - -This file is reserved for Agent 2 prompts and handoff summaries. - -Overwrite this file in future multi-agent rounds. diff --git a/agent3.md b/agent3.md deleted file mode 100644 index 01f70d7..0000000 --- a/agent3.md +++ /dev/null @@ -1,5 +0,0 @@ -# Agent 3 - -This file is reserved for Agent 3 prompts and handoff summaries. - -Overwrite this file in future multi-agent rounds. diff --git a/docs/api/buffered-sink.md b/docs/api/buffered-sink.md new file mode 100644 index 0000000..b03b0ef --- /dev/null +++ b/docs/api/buffered-sink.md @@ -0,0 +1,66 @@ +--- +name: buffered-sink +group: api +category: sink +update-time: 20260520 +description: Create a sink that buffers records and flushes them manually or at a threshold. +key-word: + - sink + - buffer + - flush + - public +--- + +## Buffered-sink + +Create a sink that buffers records before forwarding them to another sink. This helper is useful when callers want explicit or threshold-based sync batching without using the queue wrapper API. + +### Interface + +```moonbit +pub fn[S] buffered_sink(sink : S, flush_limit~ : Int = 1) -> BufferedSink[S] { +``` + +#### input + +- `sink : S` - Wrapped sink that receives flushed records. +- `flush_limit : Int` - Buffer length threshold that triggers automatic flush. + +#### output + +- `BufferedSink[S]` - Buffering sink with `pending_count()` and `flush()` helpers. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- Records are stored in an in-memory buffer until flushed. +- `flush_limit <= 0` is normalized to `1`. +- Flushing forwards the buffered records in order to the wrapped sink. + +### How to Use + +Here are some specific examples provided. + +#### When Need Manual Or Threshold-based Batch Delivery + +When writes should accumulate before they reach the destination: +```moonbit +let sink = buffered_sink(console_sink(), flush_limit=2) +let logger = Logger::new(sink, target="buffered") +``` + +In this example, records stay buffered until the threshold is reached or `flush()` is called. + +### Error Case + +e.g.: +- If callers never flush a buffer whose threshold is not reached, records remain pending. + +- If bounded dropping behavior is required instead of simple buffering, use `queued_sink(...)` or `Logger::with_queue(...)`. + +### Notes + +1. This helper is simpler than explicit queue overflow management. + +2. It is useful for synchronous batching scenarios and tests. diff --git a/docs/api/build-application-async-logger.md b/docs/api/build-application-async-logger.md new file mode 100644 index 0000000..f45e64d --- /dev/null +++ b/docs/api/build-application-async-logger.md @@ -0,0 +1,71 @@ +--- +name: build-application-async-logger +group: api +category: facade +update-time: 20260520 +description: Build the application-facing async logger facade from an AsyncLoggerBuildConfig. +key-word: + - application + - async + - facade + - public +--- + +## Build-application-async-logger + +Build an `ApplicationAsyncLogger` from `AsyncLoggerBuildConfig`. This is the application-facing async facade over `build_async_logger(...)`. + +### Interface + +```moonbit +pub fn build_application_async_logger( + config : AsyncLoggerBuildConfig, +) -> ApplicationAsyncLogger { +``` + +#### input + +- `config : AsyncLoggerBuildConfig` - Combined sync logger config and async queue/runtime config. + +#### output + +- `ApplicationAsyncLogger` - Application-facing async runtime logger. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API delegates to `build_async_logger(...)`. +- The returned logger keeps the standard async lifecycle and state helper surface. +- Use this facade when application code wants a dedicated async app-level entry point. + +### How to Use + +Here are some specific examples provided. + +#### When Need Config-driven App Async Boot + +When both sync sink shape and async queue policy are assembled as typed config: +```moonbit +let logger = build_application_async_logger( + AsyncLoggerBuildConfig::new( + logger=LoggerConfig::new(target="app.async"), + async_config=AsyncLoggerConfig::new(max_pending=8), + ), +) +``` + +In this example, the app-facing async facade is built directly from typed config. + +### Error Case + +e.g.: +- If file output is selected on a backend without native file support, backend behavior still applies when the worker drains records. + +- If the logger is never `run()`, enqueue behavior and lifecycle state still follow the normal async logger rules. + +### Notes + +1. This is a facade over the existing async runtime logger builder. + +2. Use `parse_and_build_application_async_logger(...)` when starting from JSON text. diff --git a/docs/api/build-application-logger.md b/docs/api/build-application-logger.md new file mode 100644 index 0000000..5b8270f --- /dev/null +++ b/docs/api/build-application-logger.md @@ -0,0 +1,66 @@ +--- +name: build-application-logger +group: api +category: facade +update-time: 20260520 +description: Build the application-facing configured logger facade from a LoggerConfig. +key-word: + - application + - facade + - logger + - public +--- + +## Build-application-logger + +Build an `ApplicationLogger` from `LoggerConfig`. This facade is the application-oriented sync entry point and currently aliases the configured runtime logger shape returned by `build_logger(...)`. + +### Interface + +```moonbit +pub fn build_application_logger(config : LoggerConfig) -> ApplicationLogger { +``` + +#### input + +- `config : LoggerConfig` - Fully assembled sync logger config. + +#### output + +- `ApplicationLogger` - Application-facing configured runtime logger. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API delegates to `build_logger(...)`. +- The returned value keeps the same public logging, queue, and file runtime helper surface as `ConfiguredLogger`. +- Use this facade when application boot code wants an app-specific entry name without exposing lower-level builder naming in its own code. + +### How to Use + +Here are some specific examples provided. + +#### When Need An App-level Sync Builder Entry + +When boot code assembles config values before runtime construction: +```moonbit +let logger = build_application_logger( + LoggerConfig::new(target="app", sink=SinkConfig::new(kind=SinkKind::Console)), +) +``` + +In this example, the application facade builds the same configured runtime logger shape as `build_logger(...)`. + +### Error Case + +e.g.: +- If the config uses file output on a backend without native file support, backend runtime limitations still apply after construction. + +- If queueing is not configured, queue helper values simply reflect the non-queued runtime shape. + +### Notes + +1. This is a facade API, not a separate runtime implementation. + +2. Use `parse_and_build_application_logger(...)` when starting from JSON text. diff --git a/docs/api/build-application-text-async-logger.md b/docs/api/build-application-text-async-logger.md new file mode 100644 index 0000000..64e2b7d --- /dev/null +++ b/docs/api/build-application-text-async-logger.md @@ -0,0 +1,71 @@ +--- +name: build-application-text-async-logger +group: api +category: facade +update-time: 20260520 +description: Build the application-facing text-console async logger facade from an AsyncLoggerBuildConfig. +key-word: + - application + - async + - text + - public +--- + +## Build-application-text-async-logger + +Build an `ApplicationTextAsyncLogger` from `AsyncLoggerBuildConfig`. This facade is the application-oriented async builder for the text-console runtime sink shape returned by `build_async_text_logger(...)`. + +### Interface + +```moonbit +pub fn build_application_text_async_logger( + config : AsyncLoggerBuildConfig, +) -> ApplicationTextAsyncLogger { +``` + +#### input + +- `config : AsyncLoggerBuildConfig` - Combined sync logger config and async queue/runtime config. + +#### output + +- `ApplicationTextAsyncLogger` - Application-facing async logger backed by `FormattedConsoleSink`. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API delegates to `build_async_text_logger(...)`. +- It is intended for config-driven async text console output where callers want the concrete text sink shape rather than the broader runtime sink enum wrapper. +- The returned logger keeps the usual async lifecycle helpers. + +### How to Use + +Here are some specific examples provided. + +#### When Need An App Async Builder With Text Sink Shape + +When async output should stay on text console formatting: +```moonbit +let logger = build_application_text_async_logger( + AsyncLoggerBuildConfig::new( + logger=text_console(target="app.text.async"), + async_config=AsyncLoggerConfig::new(max_pending=4), + ), +) +``` + +In this example, the async logger is built for text-console output specifically. + +### Error Case + +e.g.: +- If the embedded logger config selects a non-text sink shape, the caller should use the general async builder facade instead. + +- If runtime draining is never started, records still follow the normal async queue lifecycle rules. + +### Notes + +1. This is a narrower text-console async facade than `build_application_async_logger(...)`. + +2. It is most useful when callers want the `FormattedConsoleSink`-backed async type explicitly. diff --git a/docs/api/build-async-text-logger.md b/docs/api/build-async-text-logger.md new file mode 100644 index 0000000..0263324 --- /dev/null +++ b/docs/api/build-async-text-logger.md @@ -0,0 +1,69 @@ +--- +name: build-async-text-logger +group: api +category: async +update-time: 20260520 +description: Build an async logger with a concrete text-console sink from combined logger and async config. +key-word: + - async + - text + - builder + - public +--- + +## Build-async-text-logger + +Build an async logger directly from `AsyncLoggerBuildConfig`, but keep the concrete sink type as `FormattedConsoleSink` instead of the broader runtime sink wrapper. This helper is the text-console specific counterpart to `build_async_logger(...)`. + +### Interface + +```moonbit +pub fn build_async_text_logger(config : AsyncLoggerBuildConfig) -> AsyncLogger[@bitlogger.FormattedConsoleSink] { +``` + +#### input + +- `config : AsyncLoggerBuildConfig` - Combined sync logger config plus async queue and flush config. + +#### output + +- `AsyncLogger[FormattedConsoleSink]` - Config-built async logger backed by a concrete text console sink. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This builder converts `config.logger.sink.text_formatter` into a runtime `TextFormatter` and wires it into `text_console_sink(...)`. +- The returned logger inherits `min_level`, `target`, and timestamp behavior from `config.logger`. +- This helper is best suited to text-console output paths where callers want the concrete formatted sink type instead of `RuntimeSink`. + +### How to Use + +Here are some specific examples provided. + +#### When Need Config-built Async Text Console Output + +When async queue behavior is config-driven and output should stay on text console formatting: +```moonbit +let logger = build_async_text_logger( + AsyncLoggerBuildConfig::new( + logger=text_console(target="async.text"), + async_config=AsyncLoggerConfig::new(max_pending=4), + ), +) +``` + +In this example, the async logger is built around a text console sink rather than the generic runtime sink enum. + +### Error Case + +e.g.: +- If the logger config was not intended for text-console style output, the broader `build_async_logger(...)` path may be a better fit. + +- If the logger is never `run()`, pending records still follow the normal async queue lifecycle rules. + +### Notes + +1. This API is narrower than `build_async_logger(...)` because it preserves a concrete text sink type. + +2. It is the base builder used by the application and library async text facades. diff --git a/docs/api/build-library-async-logger.md b/docs/api/build-library-async-logger.md new file mode 100644 index 0000000..9fd42ad --- /dev/null +++ b/docs/api/build-library-async-logger.md @@ -0,0 +1,71 @@ +--- +name: build-library-async-logger +group: api +category: facade +update-time: 20260520 +description: Build the library-facing async logger facade from an AsyncLoggerBuildConfig. +key-word: + - library + - async + - facade + - public +--- + +## Build-library-async-logger + +Build a `LibraryAsyncLogger[RuntimeSink]` from `AsyncLoggerBuildConfig`. This is the library-facing async facade over the general config-driven async builder. + +### Interface + +```moonbit +pub fn build_library_async_logger( + config : AsyncLoggerBuildConfig, +) -> LibraryAsyncLogger[RuntimeSink] { +``` + +#### input + +- `config : AsyncLoggerBuildConfig` - Combined sync logger config and async queue/runtime config. + +#### output + +- `LibraryAsyncLogger[RuntimeSink]` - Library-facing async logger wrapper. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API builds the general async runtime logger and then wraps it in the narrower `LibraryAsyncLogger` facade. +- The result keeps async lifecycle operations such as `run()` and `shutdown()` while narrowing the public shape. +- `to_async_logger()` can be used to recover the underlying full async logger. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Narrower Async Type For Libraries + +When a reusable package should expose async logging but not the full runtime type directly: +```moonbit +let logger = build_library_async_logger( + AsyncLoggerBuildConfig::new( + logger=LoggerConfig::new(target="lib.async"), + async_config=AsyncLoggerConfig::new(max_pending=4), + ), +) +``` + +In this example, async runtime construction is hidden behind the library facade. + +### Error Case + +e.g.: +- If backend-specific sink limitations exist, they still apply under the facade. + +- If callers need methods outside the library facade, they must unwrap with `to_async_logger()`. + +### Notes + +1. Prefer this API when library boundaries should stay narrow. + +2. Use `parse_and_build_library_async_logger(...)` when starting from JSON text. diff --git a/docs/api/build-library-async-text-logger.md b/docs/api/build-library-async-text-logger.md new file mode 100644 index 0000000..de1229d --- /dev/null +++ b/docs/api/build-library-async-text-logger.md @@ -0,0 +1,71 @@ +--- +name: build-library-async-text-logger +group: api +category: facade +update-time: 20260520 +description: Build the library-facing text-console async logger facade from an AsyncLoggerBuildConfig. +key-word: + - library + - async + - text + - public +--- + +## Build-library-async-text-logger + +Build a `LibraryAsyncLogger[FormattedConsoleSink]` from `AsyncLoggerBuildConfig`. This facade is the library-oriented async builder for text-console runtime output. + +### Interface + +```moonbit +pub fn build_library_async_text_logger( + config : AsyncLoggerBuildConfig, +) -> LibraryAsyncLogger[FormattedConsoleSink] { +``` + +#### input + +- `config : AsyncLoggerBuildConfig` - Combined sync logger config and async queue/runtime config. + +#### output + +- `LibraryAsyncLogger[FormattedConsoleSink]` - Library-facing async logger backed by formatted console output. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API delegates to `build_async_text_logger(...)` and then wraps the result as `LibraryAsyncLogger`. +- It is useful when library code wants a narrow async facade while preserving a concrete text-console sink type. +- `to_async_logger()` can recover the underlying full async logger if needed. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Narrow Async Text Logger For Libraries + +When a library wants text-console async output and a narrower public type: +```moonbit +let logger = build_library_async_text_logger( + AsyncLoggerBuildConfig::new( + logger=text_console(target="lib.text.async"), + async_config=AsyncLoggerConfig::new(max_pending=4), + ), +) +``` + +In this example, the async text sink shape is preserved under the library facade. + +### Error Case + +e.g.: +- If the embedded logger config does not describe text-console output, the caller should use the broader async facade instead. + +- Normal async lifecycle expectations still apply if the logger is never run. + +### Notes + +1. This is the library-side counterpart to `build_application_text_async_logger(...)`. + +2. It is most useful when a concrete text-console async sink type matters to the caller boundary. diff --git a/docs/api/build-library-logger.md b/docs/api/build-library-logger.md new file mode 100644 index 0000000..7d0933e --- /dev/null +++ b/docs/api/build-library-logger.md @@ -0,0 +1,66 @@ +--- +name: build-library-logger +group: api +category: facade +update-time: 20260520 +description: Build the library-facing sync logger facade from a LoggerConfig. +key-word: + - library + - facade + - logger + - public +--- + +## Build-library-logger + +Build a `LibraryLogger[RuntimeSink]` from `LoggerConfig`. This facade keeps a smaller library-oriented sync surface while still using config-driven runtime assembly underneath. + +### Interface + +```moonbit +pub fn build_library_logger(config : LoggerConfig) -> LibraryLogger[RuntimeSink] { +``` + +#### input + +- `config : LoggerConfig` - Fully assembled sync logger config. + +#### output + +- `LibraryLogger[RuntimeSink]` - Library-facing logger wrapper over the configured runtime sink. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API builds a configured runtime logger first and then wraps it as `LibraryLogger`. +- The facade intentionally exposes a smaller logging surface than the full configured runtime logger. +- Call `to_logger()` if a caller must recover the underlying full logger object. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Smaller Library-facing Logging Type + +When package code should accept or produce a narrower logger facade: +```moonbit +let logger = build_library_logger( + LoggerConfig::new(target="lib", sink=SinkConfig::new(kind=SinkKind::Console)), +) +``` + +In this example, the logger is built from config and then narrowed to the library facade. + +### Error Case + +e.g.: +- If backend-specific sink limitations exist, they still apply after the facade is built. + +- If code later needs methods outside the library facade, it must unwrap with `to_logger()`. + +### Notes + +1. Prefer this facade when library APIs should not expose the full configured runtime logger type. + +2. Use `parse_and_build_library_logger(...)` when starting from JSON text. diff --git a/docs/api/callback-sink.md b/docs/api/callback-sink.md new file mode 100644 index 0000000..1bc6adc --- /dev/null +++ b/docs/api/callback-sink.md @@ -0,0 +1,69 @@ +--- +name: callback-sink +group: api +category: sink +update-time: 20260520 +description: Create a sink that forwards records to a user callback. +key-word: + - sink + - callback + - record + - public +--- + +## Callback-sink + +Create a sink that forwards each `Record` to a callback. This is the most direct built-in integration hook for tests, adapters, and custom side effects. + +### Interface + +```moonbit +pub fn callback_sink(callback : (Record) -> Unit) -> CallbackSink { +``` + +#### input + +- `callback : (Record) -> Unit` - Function called for each emitted record. + +#### output + +- `CallbackSink` - Sink that forwards records to the callback. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- The callback receives the full structured record. +- This sink is useful for tests, custom bridges, or integration code that wants raw record access. +- Formatting is not applied automatically because the callback works on `Record` values directly. + +### How to Use + +Here are some specific examples provided. + +#### When Need To Capture Structured Records + +When tests or adapters want direct access to target, message, and fields: +```moonbit +let logger = Logger::new( + callback_sink(fn(rec) { + println(rec.target) + }), + target="hook", +) +``` + +In this example, the callback sees the structured record rather than pre-rendered text. + +### Error Case + +e.g.: +- If text output is needed instead of raw records, use `text_callback_sink(...)`. + +- Callback behavior is fully user-defined, so failures inside the callback are outside the sink's own API contract. + +### Notes + +1. This sink is commonly useful in tests and adapters. + +2. It composes naturally with filter, patch, fanout, and queue wrappers. diff --git a/docs/api/color-mode-label.md b/docs/api/color-mode-label.md new file mode 100644 index 0000000..6d9a58d --- /dev/null +++ b/docs/api/color-mode-label.md @@ -0,0 +1,64 @@ +--- +name: color-mode-label +group: api +category: formatter +update-time: 20260520 +description: Convert a ColorMode value into its stable string label. +key-word: + - color + - formatter + - label + - public +--- + +## Color-mode-label + +Convert `ColorMode` into its stable string label. This helper is useful for diagnostics, tests, and config inspection output that should mirror the built-in color mode names. + +### Interface + +```moonbit +pub fn color_mode_label(mode : ColorMode) -> String { +``` + +#### input + +- `mode : ColorMode` - Color mode enum value to label. + +#### output + +- `String` - Stable label such as `never`, `auto`, or `always`. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- The returned strings match the built-in color mode vocabulary. +- This helper is presentation-oriented and does not by itself enable or disable color rendering. +- It is useful when tests or diagnostics should expose the configured color policy clearly. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Readable Color Mode Name + +When config or test output should include the current color policy: +```moonbit +let label = color_mode_label(ColorMode::Always) +``` + +In this example, `label` becomes `"always"`. + +### Error Case + +e.g.: +- There is no failure path for valid `ColorMode` values. + +- If code needs rendering behavior rather than display text, the enum value itself is usually more useful than the label string. + +### Notes + +1. This helper is mostly useful for readable inspection and assertions. + +2. It is a natural companion to `color_support_label(...)`. diff --git a/docs/api/color-support-label.md b/docs/api/color-support-label.md new file mode 100644 index 0000000..665d5e9 --- /dev/null +++ b/docs/api/color-support-label.md @@ -0,0 +1,64 @@ +--- +name: color-support-label +group: api +category: formatter +update-time: 20260520 +description: Convert a ColorSupport value into its stable string label. +key-word: + - color + - formatter + - label + - public +--- + +## Color-support-label + +Convert `ColorSupport` into its stable string label. This helper is useful for diagnostics, tests, and config-oriented output that should mirror the built-in color support names. + +### Interface + +```moonbit +pub fn color_support_label(support : ColorSupport) -> String { +``` + +#### input + +- `support : ColorSupport` - Color support enum value to label. + +#### output + +- `String` - Stable label such as `basic` or `truecolor`. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- The returned strings are stable enum labels used by config and tests. +- This helper is presentation-oriented and does not change formatter behavior by itself. +- It is useful when code should display or assert a readable color support mode. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Readable Color Support Name + +When diagnostics or tests should show the selected color capability: +```moonbit +let label = color_support_label(ColorSupport::Basic) +``` + +In this example, `label` becomes `"basic"`. + +### Error Case + +e.g.: +- There is no failure path for valid `ColorSupport` values. + +- If code needs to choose rendering behavior, the enum value itself is usually more useful than its label string. + +### Notes + +1. This helper is mostly useful for readable output and assertions. + +2. It pairs naturally with config parsing and formatter inspection tests. diff --git a/docs/api/console-sink.md b/docs/api/console-sink.md new file mode 100644 index 0000000..ccb65ea --- /dev/null +++ b/docs/api/console-sink.md @@ -0,0 +1,61 @@ +--- +name: console-sink +group: api +category: sink +update-time: 20260520 +description: Create the built-in plain console sink for synchronous loggers. +key-word: + - sink + - console + - sync + - public +--- + +## Console-sink + +Create the built-in plain console sink. This is the minimal terminal output sink commonly passed to `Logger::new(...)`. + +### Interface + +```moonbit +pub fn console_sink() -> ConsoleSink { +``` + +#### output + +- `ConsoleSink` - Sink that writes records to the console using default text formatting. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This sink writes formatted text to the console. +- It is the simplest built-in sink for direct synchronous logging. +- Use other sink constructors when JSON, custom text formatting, callbacks, routing, or buffering are needed. + +### How to Use + +Here are some specific examples provided. + +#### When Need Minimal Console Output + +When a logger only needs default terminal output: +```moonbit +let logger = Logger::new(console_sink(), target="app") +logger.info("ready") +``` + +In this example, the logger writes directly to the console sink. + +### Error Case + +e.g.: +- If richer formatting or routing is required, this sink may be too minimal and another sink constructor should be used. + +- Console output behavior still depends on the current runtime environment. + +### Notes + +1. This is the most common sink constructor for simple sync examples. + +2. Use `json_console_sink()` or `text_console_sink(...)` when output shape matters more explicitly. diff --git a/docs/api/default-library-logger.md b/docs/api/default-library-logger.md new file mode 100644 index 0000000..18ba2b4 --- /dev/null +++ b/docs/api/default-library-logger.md @@ -0,0 +1,63 @@ +--- +name: default-library-logger +group: api +category: facade +update-time: 20260520 +description: Create the default library-facing console logger facade from shared global defaults. +key-word: + - library + - facade + - default + - public +--- + +## Default-library-logger + +Create a `LibraryLogger[ConsoleSink]` from the current shared default console logger settings. This is the narrow library-facing counterpart to `default_logger()`. + +### Interface + +```moonbit +pub fn default_library_logger() -> LibraryLogger[ConsoleSink] { +``` + +#### output + +- `LibraryLogger[ConsoleSink]` - Library-facing console logger built from the current shared defaults. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API wraps `default_logger()` as a library facade. +- Each call reflects the current shared default minimum level and default target at that moment. +- The returned value exposes the narrower `LibraryLogger` surface rather than the full `Logger` surface. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Default Logger But Want A Narrower Facade + +When a library should adopt the shared console defaults without exposing the full logger type: +```moonbit +let logger = default_library_logger() +if logger.is_enabled(Level::Info) { + logger.info("ready") +} +``` + +In this example, the library facade mirrors the current global defaults. + +### Error Case + +e.g.: +- If the shared default target is empty, the returned logger is still valid. + +- Later changes to shared defaults do not mutate an already-created facade value. + +### Notes + +1. Use `to_logger()` if callers need the full sync logger surface. + +2. This helper is useful for library-facing APIs that should stay narrower than `Logger`. diff --git a/docs/api/default-logger-config.md b/docs/api/default-logger-config.md new file mode 100644 index 0000000..10007b6 --- /dev/null +++ b/docs/api/default-logger-config.md @@ -0,0 +1,60 @@ +--- +name: default-logger-config +group: api +category: config +update-time: 20260520 +description: Create the default LoggerConfig used by config-driven logger builders. +key-word: + - logger + - config + - default + - public +--- + +## Default-logger-config + +Create the default `LoggerConfig` used by config-driven logger builders. This helper is useful when callers want the library's baseline top-level config value explicitly before customization. + +### Interface + +```moonbit +pub fn default_logger_config() -> LoggerConfig { +``` + +#### output + +- `LoggerConfig` - Default top-level logger config. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper returns the same baseline config shape used by `LoggerConfig::new()` defaults. +- It includes the default minimum level, empty target, disabled timestamp, default sink config, and no queue wrapper. +- It is useful for explicit config composition when callers want a known baseline object. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Baseline Top-level Config Value + +When config code prefers to start from the full default object: +```moonbit +let config = default_logger_config() +``` + +In this example, the default logger config is available as a concrete value for later adjustment or serialization. + +### Error Case + +e.g.: +- There is no failure path for retrieving the default config value. + +- If runtime construction is needed immediately, pass the config to `build_logger(...)` or use a runtime logger constructor directly. + +### Notes + +1. This helper is the top-level default config entry point. + +2. It is useful for explicit config-first workflows and tests. diff --git a/docs/api/default-sink-config.md b/docs/api/default-sink-config.md new file mode 100644 index 0000000..92a819b --- /dev/null +++ b/docs/api/default-sink-config.md @@ -0,0 +1,60 @@ +--- +name: default-sink-config +group: api +category: config +update-time: 20260520 +description: Create the default SinkConfig used by logger config helpers. +key-word: + - sink + - config + - default + - public +--- + +## Default-sink-config + +Create the default `SinkConfig` used by logger config helpers. This helper is useful when callers want the library's baseline sink config value explicitly. + +### Interface + +```moonbit +pub fn default_sink_config() -> SinkConfig { +``` + +#### output + +- `SinkConfig` - Default sink config value. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper returns the same baseline sink config used by `LoggerConfig::new(...)` defaults. +- The default sink config is console-oriented unless later replaced by explicit config composition. +- It is a typed config object, not a runtime sink instance. + +### How to Use + +Here are some specific examples provided. + +#### When Need An Explicit Baseline Sink Config + +When config assembly wants the default sink as a concrete value: +```moonbit +let sink = default_sink_config() +``` + +In this example, the baseline sink config can be reused or embedded explicitly. + +### Error Case + +e.g.: +- There is no failure path for retrieving the default sink config. + +- If a real sink instance is required for direct `Logger::new(...)` code paths, use a sink constructor such as `console_sink()` instead. + +### Notes + +1. This helper is for config-driven assembly, not runtime sink wiring. + +2. It is most useful in explicit config composition code. diff --git a/docs/api/default-style-tag-registry.md b/docs/api/default-style-tag-registry.md new file mode 100644 index 0000000..125f74a --- /dev/null +++ b/docs/api/default-style-tag-registry.md @@ -0,0 +1,60 @@ +--- +name: default-style-tag-registry +group: api +category: formatter +update-time: 20260520 +description: Create the built-in style tag registry containing default semantic and color tags. +key-word: + - style + - registry + - default + - public +--- + +## Default-style-tag-registry + +Create the built-in `StyleTagRegistry` containing the library's default style tags. This helper is useful when callers want to start from the standard tag set and then extend or override it. + +### Interface + +```moonbit +pub fn default_style_tag_registry() -> StyleTagRegistry { +``` + +#### output + +- `StyleTagRegistry` - Registry seeded with built-in tags and aliases. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- The returned registry contains the library's built-in style tag set. +- Callers can extend or override entries before attaching the registry to a formatter. +- This helper is useful when custom tags should coexist with built-in semantic tags. + +### How to Use + +Here are some specific examples provided. + +#### When Need Built-in Tags Plus Local Overrides + +When a formatter should keep defaults but customize one tag: +```moonbit +let tags = default_style_tag_registry().set_tag("success", fg=Some("#00ffaa"), underline=true) +``` + +In this example, the built-in registry is reused and then locally overridden. + +### Error Case + +e.g.: +- If the formatter disables style markup, built-in tags may not be applied even though the registry exists. + +- If callers need a clean registry with no built-in tags, use `style_tag_registry()` instead. + +### Notes + +1. This helper is the easiest way to preserve the standard tag vocabulary. + +2. It is commonly paired with `text_formatter(...).with_style_tags(...)`. diff --git a/docs/api/default-text-formatter-config.md b/docs/api/default-text-formatter-config.md new file mode 100644 index 0000000..02e8bcb --- /dev/null +++ b/docs/api/default-text-formatter-config.md @@ -0,0 +1,60 @@ +--- +name: default-text-formatter-config +group: api +category: config +update-time: 20260520 +description: Create the default TextFormatterConfig used by config and preset helpers. +key-word: + - formatter + - config + - default + - public +--- + +## Default-text-formatter-config + +Create the default `TextFormatterConfig` used by config builders and presets. This helper is useful when callers want the library default config value explicitly rather than relying on optional parameter defaults. + +### Interface + +```moonbit +pub fn default_text_formatter_config() -> TextFormatterConfig { +``` + +#### output + +- `TextFormatterConfig` - Default serializable formatter config value. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper returns the same baseline config value used by `text_console(...)`, `file(...)`, and `SinkConfig::new(...)` defaults. +- It is a config object, not a runtime `TextFormatter`. +- Call `to_formatter()` when a runtime formatter is needed. + +### How to Use + +Here are some specific examples provided. + +#### When Need To Start From The Default Formatter Config Explicitly + +When config code wants the baseline value before adjusting fields: +```moonbit +let base = default_text_formatter_config() +``` + +In this example, the default formatter config is available as a concrete value instead of an implicit optional argument default. + +### Error Case + +e.g.: +- There is no failure path for retrieving the default config value. + +- If a runtime formatter is required immediately, this helper alone is not enough because it returns config rather than a formatter object. + +### Notes + +1. Use this helper for explicit config composition. + +2. Use `text_formatter(...)` when you want a runtime formatter directly. diff --git a/docs/api/fanout-sink.md b/docs/api/fanout-sink.md new file mode 100644 index 0000000..8b8bd00 --- /dev/null +++ b/docs/api/fanout-sink.md @@ -0,0 +1,68 @@ +--- +name: fanout-sink +group: api +category: sink +update-time: 20260520 +description: Create a sink that writes each record to two sinks. +key-word: + - sink + - fanout + - routing + - public +--- + +## Fanout-sink + +Create a sink that writes every record to two underlying sinks. This helper is useful when the same log stream should be duplicated across multiple destinations. + +### Interface + +```moonbit +pub fn[A, B] fanout_sink(left : A, right : B) -> FanoutSink[A, B] { +``` + +#### input + +- `left : A` - First sink destination. +- `right : B` - Second sink destination. + +#### output + +- `FanoutSink[A, B]` - Sink that duplicates records to both destinations. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- Each record is written to both sinks. +- The right side receives a copied record so the two writes remain independent at the record value level. +- This helper is useful for combinations such as console plus JSON, or console plus callback capture. + +### How to Use + +Here are some specific examples provided. + +#### When Need Dual Output Paths + +When the same records should go to both human and machine-oriented outputs: +```moonbit +let logger = Logger::new( + fanout_sink(console_sink(), json_console_sink()), + target="dual", +) +``` + +In this example, each record is written to both console sinks. + +### Error Case + +e.g.: +- If only one path should receive a record conditionally, use `split_sink(...)` instead. + +- Sink-specific failures still follow the behavior of the wrapped sinks. + +### Notes + +1. This helper is a duplication primitive, not a conditional router. + +2. It is often useful in examples and test capture setups. diff --git a/docs/api/filter-sink.md b/docs/api/filter-sink.md new file mode 100644 index 0000000..231d494 --- /dev/null +++ b/docs/api/filter-sink.md @@ -0,0 +1,67 @@ +--- +name: filter-sink +group: api +category: sink +update-time: 20260520 +description: Create a sink that forwards only records matching a predicate. +key-word: + - sink + - filter + - predicate + - public +--- + +## Filter-sink + +Create a sink that forwards only records matching a predicate. This helper is the sink-level counterpart to `Logger::with_filter(...)`. + +### Interface + +```moonbit +pub fn[S] filter_sink(sink : S, predicate : (Record) -> Bool) -> FilterSink[S] { +``` + +#### input + +- `sink : S` - Wrapped sink receiving records that pass the predicate. +- `predicate : (Record) -> Bool` - Filtering function evaluated for each record. + +#### output + +- `FilterSink[S]` - Predicate-filtering sink. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- Only records for which the predicate returns `true` are forwarded. +- This helper is useful for sink-first composition and explicit routing graphs. +- Use the logger-level helper when the filter should be attached after `Logger::new(...)` instead. + +### How to Use + +Here are some specific examples provided. + +#### When Need Predicate Filtering At Sink Construction Time + +When a sink graph should reject records before they reach the destination: +```moonbit +let sink = filter_sink(console_sink(), fn(rec) { + rec.target == "kept" +}) +``` + +In this example, only matching records are forwarded to the wrapped sink. + +### Error Case + +e.g.: +- If record selection should be attached to an already-built logger, use `with_filter(...)` instead. + +- Predicate logic is caller-defined, so accidental over-filtering comes from predicate choice. + +### Notes + +1. This helper is useful for sink-first composition graphs. + +2. It works well with predicate builders such as `target_is(...)` and `all_of(...)`. diff --git a/docs/api/global-style-tag-registry.md b/docs/api/global-style-tag-registry.md new file mode 100644 index 0000000..f229d6a --- /dev/null +++ b/docs/api/global-style-tag-registry.md @@ -0,0 +1,62 @@ +--- +name: global-style-tag-registry +group: api +category: formatter +update-time: 20260520 +description: Read the shared global style tag registry used by formatters without local tag overrides. +key-word: + - style + - registry + - global + - public +--- + +## Global-style-tag-registry + +Read the shared global `StyleTagRegistry`. This helper is useful when code wants to inspect or reuse the current process-wide formatter tag registry. + +### Interface + +```moonbit +pub fn global_style_tag_registry() -> StyleTagRegistry { +``` + +#### output + +- `StyleTagRegistry` - Current shared global style tag registry. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper reads the shared global registry used when a formatter has no local registry override. +- It is useful for inspection, temporary replacement, or restoration workflows. +- Local formatter registries still take priority over the global registry. + +### How to Use + +Here are some specific examples provided. + +#### When Need To Snapshot And Restore Global Tags + +When tests or boot code temporarily replace the shared registry: +```moonbit +let previous = global_style_tag_registry() +set_global_style_tag_registry(style_tag_registry().set_tag("accent", fg=Some("#123456"))) +set_global_style_tag_registry(previous) +``` + +In this example, the current global registry is captured and later restored. + +### Error Case + +e.g.: +- If a formatter already has local style tags, global tag changes may not affect that formatter. + +- This helper only reads the shared registry; it does not mutate it. + +### Notes + +1. Use `set_global_style_tag_registry(...)` or `reset_global_style_tag_registry()` for mutation. + +2. Global registry changes should be made carefully because they affect subsequent formatting without local overrides. diff --git a/docs/api/index.md b/docs/api/index.md index f85e42e..5ee170a 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -43,6 +43,9 @@ BitLogger API navigation. - [set-default-min-level.md](./set-default-min-level.md) - [set-default-target.md](./set-default-target.md) - [default-logger.md](./default-logger.md) +- [global-style-tag-registry.md](./global-style-tag-registry.md) +- [set-global-style-tag-registry.md](./set-global-style-tag-registry.md) +- [reset-global-style-tag-registry.md](./reset-global-style-tag-registry.md) - [global-log.md](./global-log.md) - [global-trace.md](./global-trace.md) - [global-debug.md](./global-debug.md) @@ -53,10 +56,17 @@ BitLogger API navigation. ## Formatter and fields - [field.md](./field.md) +- [text-style.md](./text-style.md) +- [style-tag-registry.md](./style-tag-registry.md) +- [default-style-tag-registry.md](./default-style-tag-registry.md) - [text-formatter.md](./text-formatter.md) - [text-formatter-config.md](./text-formatter-config.md) +- [default-text-formatter-config.md](./default-text-formatter-config.md) - [text-formatter-config-to-json.md](./text-formatter-config-to-json.md) - [stringify-text-formatter-config.md](./stringify-text-formatter-config.md) +- [color-support-label.md](./color-support-label.md) +- [style-markup-mode-label.md](./style-markup-mode-label.md) +- [color-mode-label.md](./color-mode-label.md) - [fields.md](./fields.md) ## Record and level @@ -68,6 +78,18 @@ BitLogger API navigation. ## Sink and file +- [console-sink.md](./console-sink.md) +- [json-console-sink.md](./json-console-sink.md) +- [text-console-sink.md](./text-console-sink.md) +- [callback-sink.md](./callback-sink.md) +- [text-callback-sink.md](./text-callback-sink.md) +- [fanout-sink.md](./fanout-sink.md) +- [split-sink.md](./split-sink.md) +- [split-by-level.md](./split-by-level.md) +- [buffered-sink.md](./buffered-sink.md) +- [queued-sink.md](./queued-sink.md) +- [filter-sink.md](./filter-sink.md) +- [patch-sink.md](./patch-sink.md) - [file-sink.md](./file-sink.md) - [file-rotation.md](./file-rotation.md) - [file-sink-policy-to-json.md](./file-sink-policy-to-json.md) @@ -104,7 +126,9 @@ BitLogger API navigation. - [queue-config.md](./queue-config.md) - [queue-config-to-json.md](./queue-config-to-json.md) - [stringify-queue-config.md](./stringify-queue-config.md) +- [default-sink-config.md](./default-sink-config.md) - [logger-config.md](./logger-config.md) +- [default-logger-config.md](./default-logger-config.md) - [logger-config-to-json.md](./logger-config-to-json.md) - [stringify-logger-config.md](./stringify-logger-config.md) - [parse-logger-config-text.md](./parse-logger-config-text.md) @@ -166,13 +190,29 @@ BitLogger API navigation. - [async-runtime-state-to-json.md](./async-runtime-state-to-json.md) - [stringify-async-runtime-state.md](./stringify-async-runtime-state.md) - [async-logger-config.md](./async-logger-config.md) +- [parse-async-logger-config-text.md](./parse-async-logger-config-text.md) - [async-logger-config-to-json.md](./async-logger-config-to-json.md) - [stringify-async-logger-config.md](./stringify-async-logger-config.md) - [parse-async-logger-build-config-text.md](./parse-async-logger-build-config-text.md) - [build-async-logger.md](./build-async-logger.md) +- [build-async-text-logger.md](./build-async-text-logger.md) - [async-logger-build-config-to-json.md](./async-logger-build-config-to-json.md) - [stringify-async-logger-build-config.md](./stringify-async-logger-build-config.md) +## Application and library facades + +- [build-application-logger.md](./build-application-logger.md) +- [parse-and-build-application-logger.md](./parse-and-build-application-logger.md) +- [build-library-logger.md](./build-library-logger.md) +- [parse-and-build-library-logger.md](./parse-and-build-library-logger.md) +- [default-library-logger.md](./default-library-logger.md) +- [build-application-async-logger.md](./build-application-async-logger.md) +- [build-application-text-async-logger.md](./build-application-text-async-logger.md) +- [parse-and-build-application-async-logger.md](./parse-and-build-application-async-logger.md) +- [build-library-async-logger.md](./build-library-async-logger.md) +- [build-library-async-text-logger.md](./build-library-async-text-logger.md) +- [parse-and-build-library-async-logger.md](./parse-and-build-library-async-logger.md) + ## Configured logger runtime - [configured-logger-flush.md](./configured-logger-flush.md) diff --git a/docs/api/json-console-sink.md b/docs/api/json-console-sink.md new file mode 100644 index 0000000..e45fa53 --- /dev/null +++ b/docs/api/json-console-sink.md @@ -0,0 +1,61 @@ +--- +name: json-console-sink +group: api +category: sink +update-time: 20260520 +description: Create the built-in JSON console sink for structured synchronous logging. +key-word: + - sink + - json + - console + - public +--- + +## Json-console-sink + +Create the built-in JSON console sink. This sink writes records as structured JSON text and is useful when stdout is consumed by machines rather than humans. + +### Interface + +```moonbit +pub fn json_console_sink() -> JsonConsoleSink { +``` + +#### output + +- `JsonConsoleSink` - Sink that writes records to the console as JSON. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This sink emits JSON rather than human-focused text formatting. +- It is a direct synchronous sink that can be passed to `Logger::new(...)`. +- Use it when structured logs should be parsed, shipped, or inspected programmatically. + +### How to Use + +Here are some specific examples provided. + +#### When Need Structured Stdout Logs + +When log consumers expect machine-readable output: +```moonbit +let logger = Logger::new(json_console_sink(), target="api") +logger.info("ready", fields=[field("service", "bitlogger")]) +``` + +In this example, the emitted console line is JSON-shaped. + +### Error Case + +e.g.: +- If human-focused text formatting is required, use a text console sink instead. + +- Console output still depends on the current runtime environment. + +### Notes + +1. This sink is useful for structured stdout pipelines. + +2. It pairs naturally with field-heavy logging. diff --git a/docs/api/parse-and-build-application-async-logger.md b/docs/api/parse-and-build-application-async-logger.md new file mode 100644 index 0000000..c5a08ae --- /dev/null +++ b/docs/api/parse-and-build-application-async-logger.md @@ -0,0 +1,68 @@ +--- +name: parse-and-build-application-async-logger +group: api +category: facade +update-time: 20260520 +description: Parse JSON async build config text and build the application-facing async logger facade. +key-word: + - application + - async + - parse + - public +--- + +## Parse-and-build-application-async-logger + +Parse raw JSON async build config text and build an `ApplicationAsyncLogger` in one step. This facade is the application-oriented counterpart to `parse_async_logger_build_config_text(...)` plus `build_application_async_logger(...)`. + +### Interface + +```moonbit +pub fn parse_and_build_application_async_logger( + input : String, +) -> ApplicationAsyncLogger raise { +``` + +#### input + +- `input : String` - Raw JSON async logger build config text. + +#### output + +- `ApplicationAsyncLogger` - Application-facing async runtime logger. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API parses async build config text first, then builds the async application facade. +- Both the embedded sync logger config and async queue/runtime config are validated by the parser layer. +- The returned logger keeps the normal async lifecycle and state helpers. + +### How to Use + +Here are some specific examples provided. + +#### When Need App Async Boot Directly From JSON + +When async config is sourced as text and should become a running-capable facade immediately: +```moonbit +let logger = parse_and_build_application_async_logger( + "{\"logger\":{\"target\":\"app.async\",\"sink\":{\"kind\":\"console\"}},\"async_config\":{\"max_pending\":4,\"overflow\":\"DropNewest\",\"max_batch\":1,\"linger_ms\":0,\"flush\":\"Never\"}}", +) +``` + +In this example, text parsing and async logger construction happen in one facade call. + +### Error Case + +e.g.: +- If the JSON text is malformed, parsing raises an error. + +- If the embedded config is invalid, parsing raises before the async facade is returned. + +### Notes + +1. Use this facade when application boot starts from JSON text. + +2. Use `build_application_async_logger(...)` when config is already typed as `AsyncLoggerBuildConfig`. diff --git a/docs/api/parse-and-build-application-logger.md b/docs/api/parse-and-build-application-logger.md new file mode 100644 index 0000000..8fcfb5b --- /dev/null +++ b/docs/api/parse-and-build-application-logger.md @@ -0,0 +1,68 @@ +--- +name: parse-and-build-application-logger +group: api +category: facade +update-time: 20260520 +description: Parse JSON logger config text and build the application-facing sync logger facade. +key-word: + - application + - facade + - parse + - public +--- + +## Parse-and-build-application-logger + +Parse raw JSON config text and build an `ApplicationLogger` in one step. This facade is the application-oriented counterpart to `parse_and_build_logger(...)`. + +### Interface + +```moonbit +pub fn parse_and_build_application_logger( + input : String, +) -> ApplicationLogger raise ConfigError { +``` + +#### input + +- `input : String` - Raw JSON logger config text. + +#### output + +- `ApplicationLogger` - Application-facing configured runtime logger built from parsed config. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API delegates to `parse_and_build_logger(...)`. +- JSON parsing and config validation happen before the logger is built. +- The returned logger keeps the same queue and file helper surface as other configured sync runtime loggers. + +### How to Use + +Here are some specific examples provided. + +#### When Need Direct JSON Bootstrapping For Applications + +When config is stored as text and should be built immediately: +```moonbit +let logger = parse_and_build_application_logger( + "{\"min_level\":\"warn\",\"target\":\"app\",\"sink\":{\"kind\":\"console\"}}", +) +``` + +In this example, parsing and runtime construction are combined into one facade call. + +### Error Case + +e.g.: +- If the JSON is malformed, a `ConfigError` is raised. + +- If the parsed config is invalid, such as an empty file sink path, a `ConfigError` is raised. + +### Notes + +1. Use this facade when application code wants a text-to-runtime entry point. + +2. Use `build_application_logger(...)` when the config is already typed as `LoggerConfig`. diff --git a/docs/api/parse-and-build-library-async-logger.md b/docs/api/parse-and-build-library-async-logger.md new file mode 100644 index 0000000..b612e68 --- /dev/null +++ b/docs/api/parse-and-build-library-async-logger.md @@ -0,0 +1,68 @@ +--- +name: parse-and-build-library-async-logger +group: api +category: facade +update-time: 20260520 +description: Parse JSON async build config text and build the library-facing async logger facade. +key-word: + - library + - async + - parse + - public +--- + +## Parse-and-build-library-async-logger + +Parse raw JSON async build config text and build a `LibraryAsyncLogger[RuntimeSink]` in one step. This facade is the text-driven library counterpart to the general async config parser plus builder flow. + +### Interface + +```moonbit +pub fn parse_and_build_library_async_logger( + input : String, +) -> LibraryAsyncLogger[RuntimeSink] raise { +``` + +#### input + +- `input : String` - Raw JSON async logger build config text. + +#### output + +- `LibraryAsyncLogger[RuntimeSink]` - Library-facing async runtime logger wrapper. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API parses async build config text, validates it, builds the async runtime logger, and narrows it to the library facade. +- The resulting facade keeps async lifecycle helpers while exposing a smaller public surface. +- `to_async_logger()` can recover the underlying async logger when a wider API is required. + +### How to Use + +Here are some specific examples provided. + +#### When Need Text-driven Async Library Bootstrapping + +When a package accepts raw config text but wants a narrower async facade output: +```moonbit +let logger = parse_and_build_library_async_logger( + "{\"logger\":{\"target\":\"lib.async\",\"sink\":{\"kind\":\"console\"}},\"async_config\":{\"max_pending\":4,\"overflow\":\"DropNewest\",\"max_batch\":1,\"linger_ms\":0,\"flush\":\"Never\"}}", +) +``` + +In this example, parsing and library-facade construction happen together. + +### Error Case + +e.g.: +- If the JSON text is malformed, parsing raises an error. + +- If the embedded config is invalid, parsing raises before the library facade is returned. + +### Notes + +1. This is the narrow async library parse-and-build facade. + +2. Use `build_library_async_logger(...)` when the config is already typed. diff --git a/docs/api/parse-and-build-library-logger.md b/docs/api/parse-and-build-library-logger.md new file mode 100644 index 0000000..11b5268 --- /dev/null +++ b/docs/api/parse-and-build-library-logger.md @@ -0,0 +1,68 @@ +--- +name: parse-and-build-library-logger +group: api +category: facade +update-time: 20260520 +description: Parse JSON logger config text and build the library-facing sync logger facade. +key-word: + - library + - facade + - parse + - public +--- + +## Parse-and-build-library-logger + +Parse raw JSON config text and build a `LibraryLogger[RuntimeSink]` in one step. This facade is the text-driven library counterpart to `parse_and_build_logger(...)`. + +### Interface + +```moonbit +pub fn parse_and_build_library_logger( + input : String, +) -> LibraryLogger[RuntimeSink] raise ConfigError { +``` + +#### input + +- `input : String` - Raw JSON logger config text. + +#### output + +- `LibraryLogger[RuntimeSink]` - Library-facing wrapper around the configured runtime logger. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This API parses config text, validates it, builds the configured logger, and wraps it as a library facade. +- The returned facade keeps a narrower surface than the underlying configured logger. +- `to_logger()` can be used to recover the underlying full logger object when necessary. + +### How to Use + +Here are some specific examples provided. + +#### When Need Text-driven Library Bootstrapping + +When a reusable package wants config text input but a narrow logger facade output: +```moonbit +let logger = parse_and_build_library_logger( + "{\"min_level\":\"warn\",\"target\":\"lib\",\"sink\":{\"kind\":\"console\"}}", +) +``` + +In this example, parsing and library-facade construction happen in one call. + +### Error Case + +e.g.: +- If the JSON text is malformed, a `ConfigError` is raised. + +- If the parsed config is invalid, a `ConfigError` is raised before the library facade is returned. + +### Notes + +1. This is the narrow library-oriented parse-and-build sync entry point. + +2. Use `build_library_logger(...)` when the config is already typed. diff --git a/docs/api/parse-async-logger-config-text.md b/docs/api/parse-async-logger-config-text.md new file mode 100644 index 0000000..c745a0e --- /dev/null +++ b/docs/api/parse-async-logger-config-text.md @@ -0,0 +1,66 @@ +--- +name: parse-async-logger-config-text +group: api +category: async +update-time: 20260520 +description: Parse JSON text into an AsyncLoggerConfig. +key-word: + - async + - config + - parse + - public +--- + +## Parse-async-logger-config-text + +Parse raw JSON text into `AsyncLoggerConfig`. This helper is the text-entry counterpart to `AsyncLoggerConfig::new(...)` when async queue and flush policy should be configured from serialized data. + +### Interface + +```moonbit +pub fn parse_async_logger_config_text(input : String) -> AsyncLoggerConfig raise { +``` + +#### input + +- `input : String` - Raw JSON text describing async queue, batching, linger, and flush settings. + +#### output + +- `AsyncLoggerConfig` - Parsed async runtime config value. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper parses only the async config portion, not the embedded sync `LoggerConfig`. +- Parsed values follow the same normalization and enum validation rules as other async config helpers. +- Use this API when async policy comes from config text but sink choice is still assembled elsewhere. + +### How to Use + +Here are some specific examples provided. + +#### When Need Async Queue Policy From JSON + +When async queue behavior is loaded separately from sync sink config: +```moonbit +let config = parse_async_logger_config_text( + "{\"max_pending\":8,\"overflow\":\"DropOldest\",\"max_batch\":3,\"linger_ms\":25,\"flush\":\"Batch\"}", +) +``` + +In this example, async queue and flush policy are parsed from text into a typed config object. + +### Error Case + +e.g.: +- If the JSON text is malformed, parsing raises an error. + +- If enum names such as `overflow` or `flush` are unsupported, parsing raises an error. + +### Notes + +1. Use this helper when only async policy is text-driven. + +2. Use `parse_async_logger_build_config_text(...)` when both sync logger config and async config come from the same JSON payload. diff --git a/docs/api/patch-sink.md b/docs/api/patch-sink.md new file mode 100644 index 0000000..75e4b43 --- /dev/null +++ b/docs/api/patch-sink.md @@ -0,0 +1,66 @@ +--- +name: patch-sink +group: api +category: sink +update-time: 20260520 +description: Create a sink that rewrites records with a patch before forwarding them. +key-word: + - sink + - patch + - record + - public +--- + +## Patch-sink + +Create a sink that rewrites each record with a `RecordPatch` before forwarding it to another sink. This helper is the sink-level counterpart to `Logger::with_patch(...)`. + +### Interface + +```moonbit +pub fn[S] patch_sink(sink : S, patch : RecordPatch) -> PatchSink[S] { +``` + +#### input + +- `sink : S` - Wrapped sink receiving patched records. +- `patch : RecordPatch` - Record transformation applied before forwarding. + +#### output + +- `PatchSink[S]` - Patch-applying sink. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- Each record is transformed before it reaches the wrapped sink. +- This helper is useful for sink-first composition graphs and adapters. +- Use the logger-level helper when the patch should be attached after `Logger::new(...)` instead. + +### How to Use + +Here are some specific examples provided. + +#### When Need Record Rewriting At Sink Construction Time + +When sanitization or target rewriting should happen before sink delivery: +```moonbit +let sink = patch_sink(console_sink(), prefix_message("[safe] ")) +let logger = Logger::new(sink, target="auth") +``` + +In this example, records are patched before they are written to the wrapped sink. + +### Error Case + +e.g.: +- If patching should be attached to an already-built logger, use `with_patch(...)` instead. + +- Patch behavior is defined by the supplied function, so semantic mistakes come from patch logic rather than sink mechanics. + +### Notes + +1. This helper is useful for explicit sink graphs. + +2. It composes naturally with helpers such as `compose_patches(...)`. diff --git a/docs/api/queued-sink.md b/docs/api/queued-sink.md new file mode 100644 index 0000000..b0582ba --- /dev/null +++ b/docs/api/queued-sink.md @@ -0,0 +1,71 @@ +--- +name: queued-sink +group: api +category: sink +update-time: 20260520 +description: Create a sink that buffers records in an explicit queue with overflow policy control. +key-word: + - sink + - queue + - overflow + - public +--- + +## Queued-sink + +Create a sink that stores records in an explicit synchronous queue before forwarding them to another sink. This is the low-level sink constructor behind queue-style sync buffering behavior. + +### Interface + +```moonbit +pub fn[S] queued_sink( + sink : S, + max_pending~ : Int = 0, + overflow~ : QueueOverflowPolicy = QueueOverflowPolicy::DropNewest, +) -> QueuedSink[S] { +``` + +#### input + +- `sink : S` - Wrapped sink receiving drained records. +- `max_pending : Int` - Queue capacity before overflow policy applies. `0` means unbounded. +- `overflow : QueueOverflowPolicy` - Overflow behavior such as `DropNewest` or `DropOldest`. + +#### output + +- `QueuedSink[S]` - Explicit queue sink with `pending_count()`, `dropped_count()`, `drain()`, and `flush()` helpers. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- Records are enqueued first and only reach the wrapped sink when drained or flushed. +- `max_pending=0` means the queue is not bounded by capacity. +- Overflow behavior controls whether the incoming record is dropped or the oldest queued record is replaced. + +### How to Use + +Here are some specific examples provided. + +#### When Need Low-level Explicit Queue Composition + +When a sync logger should own a queue sink directly: +```moonbit +let sink = queued_sink(console_sink(), max_pending=2, overflow=QueueOverflowPolicy::DropOldest) +let logger = Logger::new(sink, target="queue") +``` + +In this example, records stay pending until the queue is drained or flushed. + +### Error Case + +e.g.: +- If the queue is bounded too tightly, overflow may drop records during bursts. + +- If callers never drain or flush, queued records remain pending. + +### Notes + +1. This helper is the sink-level alternative to `Logger::with_queue(...)` and config-side `with_queue(...)`. + +2. Use the higher-level APIs when you do not need to manipulate the queue sink directly. diff --git a/docs/api/reset-global-style-tag-registry.md b/docs/api/reset-global-style-tag-registry.md new file mode 100644 index 0000000..fb65640 --- /dev/null +++ b/docs/api/reset-global-style-tag-registry.md @@ -0,0 +1,57 @@ +--- +name: reset-global-style-tag-registry +group: api +category: formatter +update-time: 20260520 +description: Reset the shared global style tag registry back to the library default. +key-word: + - style + - registry + - reset + - public +--- + +## Reset-global-style-tag-registry + +Reset the shared global `StyleTagRegistry` back to the library default. This helper is useful after temporary global overrides in tests or boot code. + +### Interface + +```moonbit +pub fn reset_global_style_tag_registry() -> Unit { +``` + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper restores the shared global registry to the built-in default tag set. +- It is the simplest cleanup path after temporary global registry customization. +- Local formatter registries remain unaffected because they are not sourced from the shared global registry. + +### How to Use + +Here are some specific examples provided. + +#### When Need To Undo Temporary Global Overrides + +When tests or boot code changed the shared registry and want the default back: +```moonbit +set_global_style_tag_registry(style_tag_registry().set_tag("accent", fg=Some("#123456"))) +reset_global_style_tag_registry() +``` + +In this example, subsequent formatters without local registries return to the library default global tag set. + +### Error Case + +e.g.: +- If a formatter already carries local tags, resetting the global registry does not change that formatter's local tag behavior. + +- This helper only resets shared global formatter state; it does not alter serialized formatter configs. + +### Notes + +1. This is the cleanup helper paired with `set_global_style_tag_registry(...)`. + +2. It is especially useful in tests that temporarily customize shared style behavior. diff --git a/docs/api/set-global-style-tag-registry.md b/docs/api/set-global-style-tag-registry.md new file mode 100644 index 0000000..6b944d7 --- /dev/null +++ b/docs/api/set-global-style-tag-registry.md @@ -0,0 +1,62 @@ +--- +name: set-global-style-tag-registry +group: api +category: formatter +update-time: 20260520 +description: Replace the shared global style tag registry used by formatters without local overrides. +key-word: + - style + - registry + - global + - public +--- + +## Set-global-style-tag-registry + +Replace the shared global `StyleTagRegistry`. This helper changes the default tag source used by formatters that do not define their own local registry. + +### Interface + +```moonbit +pub fn set_global_style_tag_registry(registry : StyleTagRegistry) -> Unit { +``` + +#### input + +- `registry : StyleTagRegistry` - New shared global registry value. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper mutates process-wide shared formatter state. +- Only formatters without local style tags read from the global registry. +- It is useful for centralized theming or tests that need predictable tag behavior. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Process-wide Custom Tag Default + +When multiple formatters should share a custom default tag registry: +```moonbit +set_global_style_tag_registry( + style_tag_registry().set_tag("accent", fg=Some("#102030"), dim=true), +) +``` + +In this example, subsequent formatters without local tag registries can resolve `accent` from the shared global registry. + +### Error Case + +e.g.: +- If local formatter tags are already present, those local tags still take priority. + +- Global mutation can affect later formatting broadly, so test code should usually restore or reset after temporary changes. + +### Notes + +1. Use `global_style_tag_registry()` to snapshot the previous value before replacement. + +2. Use `reset_global_style_tag_registry()` to restore the library default global registry. diff --git a/docs/api/split-by-level.md b/docs/api/split-by-level.md new file mode 100644 index 0000000..fb3940f --- /dev/null +++ b/docs/api/split-by-level.md @@ -0,0 +1,72 @@ +--- +name: split-by-level +group: api +category: sink +update-time: 20260520 +description: Create a split sink that routes records by minimum enabled level. +key-word: + - sink + - split + - level + - public +--- + +## Split-by-level + +Create a split sink that routes records to one of two sinks based on whether the record level is enabled at a given minimum level. + +### Interface + +```moonbit +pub fn[A, B] split_by_level( + left : A, + right : B, + min_level~ : Level = Level::Warn, +) -> SplitSink[A, B] { +``` + +#### input + +- `left : A` - Sink receiving records at or above `min_level`. +- `right : B` - Sink receiving records below `min_level`. +- `min_level : Level` - Threshold used for routing. + +#### output + +- `SplitSink[A, B]` - Level-based routing sink. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This is a convenience wrapper over `split_sink(...)`. +- High-severity and low-severity records can be separated without writing the predicate manually. +- It is useful for patterns such as warnings/errors to one destination and info/debug to another. + +### How to Use + +Here are some specific examples provided. + +#### When Need Severity-based Routing + +When warnings and errors should go to a special path: +```moonbit +let sink = split_by_level(callback_sink(fn(rec) { + println(rec.message) +}), console_sink(), min_level=Level::Warn) +``` + +In this example, `WARN` and above go to the left sink. + +### Error Case + +e.g.: +- If routing should use target, message, or fields instead of level, use `split_sink(...)` with a custom predicate. + +- Sink-specific write behavior still follows the wrapped sinks. + +### Notes + +1. This is a convenience routing helper for a common policy. + +2. It preserves the same one-side-only routing model as `split_sink(...)`. diff --git a/docs/api/split-sink.md b/docs/api/split-sink.md new file mode 100644 index 0000000..ca2c0c7 --- /dev/null +++ b/docs/api/split-sink.md @@ -0,0 +1,68 @@ +--- +name: split-sink +group: api +category: sink +update-time: 20260520 +description: Create a sink that routes records to one of two sinks using a predicate. +key-word: + - sink + - split + - routing + - public +--- + +## Split-sink + +Create a sink that routes each record to one of two sinks based on a predicate. This helper is useful for target-based or policy-based sink routing. + +### Interface + +```moonbit +pub fn[A, B] split_sink(left : A, right : B, predicate : (Record) -> Bool) -> SplitSink[A, B] { +``` + +#### input + +- `left : A` - Sink receiving records when the predicate returns `true`. +- `right : B` - Sink receiving records when the predicate returns `false`. +- `predicate : (Record) -> Bool` - Routing function evaluated for each record. + +#### output + +- `SplitSink[A, B]` - Conditional routing sink. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- The predicate decides which side receives each record. +- Unlike `fanout_sink(...)`, a record is routed to one side only. +- This helper is useful for target-aware and content-aware routing policies. + +### How to Use + +Here are some specific examples provided. + +#### When Need Predicate-based Routing + +When audit records should go to a different destination: +```moonbit +let sink = split_sink(console_sink(), json_console_sink(), fn(rec) { + rec.target == "audit" +}) +``` + +In this example, only records matching the predicate go to the left sink. + +### Error Case + +e.g.: +- If both destinations should always receive the same record, use `fanout_sink(...)` instead. + +- Predicate logic is caller-defined, so misrouting comes from predicate choice rather than sink mechanics. + +### Notes + +1. This helper is a routing primitive for synchronous sink composition. + +2. `split_by_level(...)` is a convenience wrapper for level-based routing. diff --git a/docs/api/style-markup-mode-label.md b/docs/api/style-markup-mode-label.md new file mode 100644 index 0000000..0a5d6e7 --- /dev/null +++ b/docs/api/style-markup-mode-label.md @@ -0,0 +1,64 @@ +--- +name: style-markup-mode-label +group: api +category: formatter +update-time: 20260520 +description: Convert a StyleMarkupMode value into its stable string label. +key-word: + - style + - formatter + - label + - public +--- + +## Style-markup-mode-label + +Convert `StyleMarkupMode` into its stable string label. This helper is useful for diagnostics, tests, and config inspection output. + +### Interface + +```moonbit +pub fn style_markup_mode_label(mode : StyleMarkupMode) -> String { +``` + +#### input + +- `mode : StyleMarkupMode` - Markup mode enum value to label. + +#### output + +- `String` - Stable label such as `disabled`, `builtin`, or `full`. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- The returned strings match the built-in markup mode vocabulary. +- This helper is presentation-oriented and does not change formatting behavior by itself. +- It is especially useful when tests or logs should expose the active markup policy clearly. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Readable Markup Mode Name + +When diagnostics should show which markup mode is active: +```moonbit +let label = style_markup_mode_label(StyleMarkupMode::Builtin) +``` + +In this example, `label` becomes `"builtin"`. + +### Error Case + +e.g.: +- There is no failure path for valid `StyleMarkupMode` values. + +- If code needs behavior rather than display text, the enum value itself is usually more useful than the returned label. + +### Notes + +1. This helper is mainly useful for human-readable inspection and assertions. + +2. It pairs naturally with formatter config tests and debug output. diff --git a/docs/api/style-tag-registry.md b/docs/api/style-tag-registry.md new file mode 100644 index 0000000..b1889de --- /dev/null +++ b/docs/api/style-tag-registry.md @@ -0,0 +1,60 @@ +--- +name: style-tag-registry +group: api +category: formatter +update-time: 20260520 +description: Create an empty style tag registry for custom formatter markup tags. +key-word: + - style + - registry + - formatter + - public +--- + +## Style-tag-registry + +Create an empty `StyleTagRegistry` for custom formatter style tags. This is the starting point for defining named tags such as `accent` or aliases such as `danger`. + +### Interface + +```moonbit +pub fn style_tag_registry() -> StyleTagRegistry { +``` + +#### output + +- `StyleTagRegistry` - Empty registry ready for `set_tag(...)` and alias operations. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- The returned registry starts empty. +- This helper is intended for runtime formatter customization in code. +- Registries created here can be attached to `text_formatter(...)` through `with_style_tags(...)`. + +### How to Use + +Here are some specific examples provided. + +#### When Need Custom Named Tags + +When formatter markup should define project-specific tag names: +```moonbit +let tags = style_tag_registry().set_tag("accent", fg=Some("#4cc9f0"), bold=true) +``` + +In this example, the registry becomes the container for custom named styles. + +### Error Case + +e.g.: +- If the formatter never enables the relevant style markup mode, tags in the registry may remain unused. + +- An empty registry is valid, but it does not add any custom tags by itself. + +### Notes + +1. This helper creates a runtime registry, not a serializable config map. + +2. Use `default_style_tag_registry()` when you want the built-in tag set as a starting point. diff --git a/docs/api/text-callback-sink.md b/docs/api/text-callback-sink.md new file mode 100644 index 0000000..c34a35d --- /dev/null +++ b/docs/api/text-callback-sink.md @@ -0,0 +1,73 @@ +--- +name: text-callback-sink +group: api +category: sink +update-time: 20260520 +description: Create a callback sink that forwards rendered text using a TextFormatter. +key-word: + - sink + - callback + - text + - public +--- + +## Text-callback-sink + +Create a callback sink that renders each record with a `TextFormatter` and forwards the resulting string to a callback. This is useful when integrations need formatted text without writing to the console directly. + +### Interface + +```moonbit +pub fn text_callback_sink( + formatter : TextFormatter, + callback : (String) -> Unit, +) -> FormattedCallbackSink { +``` + +#### input + +- `formatter : TextFormatter` - Formatter used to render each record. +- `callback : (String) -> Unit` - Function receiving the rendered text. + +#### output + +- `FormattedCallbackSink` - Callback sink working on rendered text. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper combines text rendering and callback delivery in one sink. +- It is the text-oriented counterpart to `callback_sink(...)`. +- Use it when a custom destination needs the final rendered text rather than the structured record object. + +### How to Use + +Here are some specific examples provided. + +#### When Need Rendered Text In A Custom Integration + +When a callback destination wants the final human-readable line: +```moonbit +let sink = text_callback_sink( + text_formatter(show_timestamp=false), + fn(line) { + println(line) + }, +) +``` + +In this example, the callback receives rendered text instead of a `Record`. + +### Error Case + +e.g.: +- If structured field access is needed, use `callback_sink(...)` instead. + +- Callback failures are outside the sink's own API contract. + +### Notes + +1. This helper is useful for tests and adapters that want human-readable output. + +2. `formatted_callback_sink(...)` is the lower-level variant when the formatter input is already a `RecordFormatter`. diff --git a/docs/api/text-console-sink.md b/docs/api/text-console-sink.md new file mode 100644 index 0000000..4395266 --- /dev/null +++ b/docs/api/text-console-sink.md @@ -0,0 +1,67 @@ +--- +name: text-console-sink +group: api +category: sink +update-time: 20260520 +description: Create a formatted console sink from a TextFormatter. +key-word: + - sink + - text + - formatter + - public +--- + +## Text-console-sink + +Create a formatted console sink from a `TextFormatter`. This sink is the direct sync constructor for human-readable console output with explicit text formatting rules. + +### Interface + +```moonbit +pub fn text_console_sink(formatter : TextFormatter) -> FormattedConsoleSink { +``` + +#### input + +- `formatter : TextFormatter` - Text formatter used to render each record. + +#### output + +- `FormattedConsoleSink` - Console sink that renders through the supplied formatter. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper adapts a `TextFormatter` into a console sink. +- It is the direct sync sink counterpart to config-driven `text_console(...)` presets. +- Use it when code-side formatter composition is preferable to config-driven assembly. + +### How to Use + +Here are some specific examples provided. + +#### When Need Explicit Text Formatting On The Console + +When console output should use a custom separator or template: +```moonbit +let logger = Logger::new( + text_console_sink(text_formatter(show_timestamp=false, separator=" | ")), + target="pretty", +) +``` + +In this example, the sink renders through the supplied formatter. + +### Error Case + +e.g.: +- If structured JSON output is required, use `json_console_sink()` instead. + +- If formatting should be data-driven rather than code-driven, prefer config or presets APIs. + +### Notes + +1. This is the most direct sync sink constructor for custom text output. + +2. `formatted_console_sink(...)` is the lower-level variant when the formatter input is already a `RecordFormatter`. diff --git a/docs/api/text-style.md b/docs/api/text-style.md new file mode 100644 index 0000000..2d63629 --- /dev/null +++ b/docs/api/text-style.md @@ -0,0 +1,76 @@ +--- +name: text-style +group: api +category: formatter +update-time: 20260520 +description: Create a reusable text style used by style tags and formatter config helpers. +key-word: + - style + - formatter + - color + - public +--- + +## Text-style + +Create a `TextStyle` describing foreground color, background color, and emphasis flags such as bold or underline. This helper is the basic style value used by formatter style tags and config-driven formatter settings. + +### Interface + +```moonbit +pub fn text_style( + fg~ : String? = None, + bg~ : String? = None, + bold~ : Bool = false, + dim~ : Bool = false, + italic~ : Bool = false, + underline~ : Bool = false, +) -> TextStyle { +``` + +#### input + +- `fg : String?` - Optional foreground color, usually a named color or hex string. +- `bg : String?` - Optional background color. +- `bold : Bool` - Whether bold emphasis is enabled. +- `dim : Bool` - Whether dim emphasis is enabled. +- `italic : Bool` - Whether italic emphasis is enabled. +- `underline : Bool` - Whether underline emphasis is enabled. + +#### output + +- `TextStyle` - Reusable style value. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper creates a plain style value; it does not register tags by itself. +- The returned style is commonly used in `style_tag_registry()` and `TextFormatterConfig::new(style_tags=...)`. +- Color interpretation still depends on formatter color settings and runtime support. + +### How to Use + +Here are some specific examples provided. + +#### When Need A Reusable Custom Tag Style + +When a formatter should define a named style tag: +```moonbit +let accent = text_style(fg=Some("#4cc9f0"), bold=true) +``` + +In this example, `accent` becomes a reusable style value that can be attached to a style tag registry or config map. + +### Error Case + +e.g.: +- If a style uses colors but the formatter disables markup or color output, visible rendering may not reflect the full style. + +- This helper does not validate higher-level tag naming because it only creates the style value itself. + +### Notes + +1. This is the basic building block for style-tag customization. + +2. Use `style_tag_registry()` when you need named tags rather than a raw style value.