Skip to main content

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    /// Creates a builder with two-space indentation and no output cap or final
44    /// newline.
45    fn default() -> Self {
46        Self {
47            indent_width: 2,
48            max_indent_levels: None,
49            trailing_newline: false,
50        }
51    }
52}
53
54impl JsonPrettyOptionsBuilder {
55    /// Sets spaces per displayed indentation level; zero is valid.
56    ///
57    /// # Parameters
58    ///
59    /// * `spaces` - Number of spaces used for each displayed level.
60    ///
61    /// # Returns
62    ///
63    /// The builder with the requested indentation width.
64    pub fn indent_width(mut self, spaces: usize) -> Self {
65        self.indent_width = spaces;
66        self
67    }
68
69    /// Caps displayed indentation while preserving real nesting state.
70    ///
71    /// `None` leaves displayed depth uncapped; `Some(0)` emits no indentation.
72    /// The cap does not limit the input's actual nesting depth.
73    ///
74    /// # Parameters
75    ///
76    /// * `maximum` - Maximum displayed indentation level, if any.
77    ///
78    /// # Returns
79    ///
80    /// The builder with the displayed-depth cap configured.
81    pub fn max_indent_levels(mut self, maximum: Option<usize>) -> Self {
82        self.max_indent_levels = maximum;
83        self
84    }
85
86    /// Controls whether one final newline is emitted.
87    ///
88    /// # Parameters
89    ///
90    /// * `enabled` - Whether to append one newline after the formatted value.
91    ///
92    /// # Returns
93    ///
94    /// The builder with the final-newline choice configured.
95    pub fn trailing_newline(mut self, enabled: bool) -> Self {
96        self.trailing_newline = enabled;
97        self
98    }
99
100    /// Builds the options. All combinations are valid.
101    ///
102    /// The `Result` return type is retained for API compatibility; this method
103    /// currently returns `Ok` for every configuration.
104    ///
105    /// # Returns
106    ///
107    /// The configured options. The result is currently always `Ok`.
108    pub fn build(self) -> Result<JsonPrettyOptions, JsonPrettyError> {
109        Ok(JsonPrettyOptions {
110            indent_width: self.indent_width,
111            max_indent_levels: self.max_indent_levels,
112            trailing_newline: self.trailing_newline,
113        })
114    }
115}