qubit_json/format/json_pretty_options_builder.rs
1// =============================================================================
2// Copyright (c) 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Builder for JSON token formatting options.
9
10use super::JsonPrettyError;
11use super::JsonPrettyOptions;
12
13/// Builder for whitespace formatting choices.
14///
15/// The displayed indentation cap does not constrain JSON nesting. All current
16/// settings are accepted by [`Self::build`].
17///
18/// # Examples
19///
20/// ```
21/// use qubit_json::format::{format_json_tokens, JsonPrettyOptions};
22///
23/// let options = JsonPrettyOptions::builder()
24/// .indent_width(2)
25/// .trailing_newline(true)
26/// .build()?;
27/// let output = format_json_tokens(b"[1]", &options, None)?;
28/// assert_eq!(output, b"[\n 1\n]\n");
29/// # Ok::<(), Box<dyn std::error::Error>>(())
30/// ```
31#[must_use = "store the updated builder or call build to use the formatting options"]
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub struct JsonPrettyOptionsBuilder {
34 /// Spaces used per displayed indentation level.
35 indent_width: usize,
36 /// Optional cap on displayed indentation depth.
37 max_indent_levels: Option<usize>,
38 /// Whether to append a final newline.
39 trailing_newline: bool,
40}
41
42impl Default for JsonPrettyOptionsBuilder {
43 fn default() -> Self {
44 Self {
45 indent_width: 2,
46 max_indent_levels: None,
47 trailing_newline: false,
48 }
49 }
50}
51
52impl JsonPrettyOptionsBuilder {
53 /// Sets spaces per displayed indentation level; zero is valid.
54 ///
55 /// # Parameters
56 ///
57 /// * `spaces` - Number of spaces used for each displayed level.
58 ///
59 /// # Returns
60 ///
61 /// The builder with the requested indentation width.
62 pub fn indent_width(mut self, spaces: usize) -> Self {
63 self.indent_width = spaces;
64 self
65 }
66
67 /// Caps displayed indentation while preserving real nesting state.
68 ///
69 /// `None` leaves displayed depth uncapped; `Some(0)` emits no indentation.
70 /// The cap does not limit the input's actual nesting depth.
71 ///
72 /// # Parameters
73 ///
74 /// * `maximum` - Maximum displayed indentation level, if any.
75 ///
76 /// # Returns
77 ///
78 /// The builder with the displayed-depth cap configured.
79 pub fn max_indent_levels(mut self, maximum: Option<usize>) -> Self {
80 self.max_indent_levels = maximum;
81 self
82 }
83
84 /// Controls whether one final newline is emitted.
85 ///
86 /// # Parameters
87 ///
88 /// * `enabled` - Whether to append one newline after the formatted value.
89 ///
90 /// # Returns
91 ///
92 /// The builder with the final-newline choice configured.
93 pub fn trailing_newline(mut self, enabled: bool) -> Self {
94 self.trailing_newline = enabled;
95 self
96 }
97
98 /// Builds the options. All combinations are valid.
99 ///
100 /// The `Result` return type is retained for API compatibility; this method
101 /// currently returns `Ok` for every configuration.
102 ///
103 /// # Returns
104 ///
105 /// The configured options. The result is currently always `Ok`.
106 pub fn build(self) -> Result<JsonPrettyOptions, JsonPrettyError> {
107 Ok(JsonPrettyOptions {
108 indent_width: self.indent_width,
109 max_indent_levels: self.max_indent_levels,
110 trailing_newline: self.trailing_newline,
111 })
112 }
113}