json_fixer/jsonfixer/
mod.rs

1pub mod json_tokenizer;
2pub mod jsonfixer_config;
3pub mod jsonfixer_error;
4pub mod jsonformatter;
5pub mod jsonparser;
6
7pub use json_tokenizer::{JsonTokenizer, Token};
8pub use jsonfixer_config::JsonFixerConfig;
9pub use jsonfixer_error::JsonFixerError;
10pub use jsonformatter::JsonFormatter;
11pub use jsonparser::JsonParser;
12
13/// A utility for parsing and fixing malformed JSON input.
14///
15/// This struct provides static methods to handle various JSON formatting and parsing tasks:
16/// - Fix common JSON syntax errors
17/// - Apply different formatting styles
18/// - Convert between JSON and Rust types (with serde feature)
19///
20/// # Features
21///
22/// - Fix malformed JSON with missing quotes, commas, and brackets
23/// - Multiple formatting options including pretty printing and key sorting
24/// - Serde integration for type conversion (optional)
25/// 
26/// # Examples
27///
28/// Basic JSON fixing:
29/// ```
30/// use json_fixer::JsonFixer;
31///
32/// let input = r#"{ name: "John", age: 30, }"#;  // Note: unquoted keys and trailing comma
33/// let result = JsonFixer::fix(input).unwrap();
34/// assert_eq!(result, r#"{"name":"John","age":30}"#);
35/// ```
36///
37/// Pretty printing:
38/// ```
39/// use json_fixer::JsonFixer;
40///
41/// let input = r#"{name:"John",age:30}"#;
42/// let result = JsonFixer::fix_pretty(input).unwrap();
43/// // Result:
44/// // {
45/// //     "name": "John",
46/// //     "age": 30
47/// // }
48/// ```
49pub struct JsonFixer;
50
51impl JsonFixer {
52    /// Fixes JSON input using custom configuration options.
53    ///
54    /// This method allows full control over the fixing and formatting process through
55    /// the provided configuration.
56    ///
57    /// # Arguments
58    ///
59    /// * `input` - The JSON string to fix
60    /// * `config` - Configuration options for fixing and formatting
61    ///
62    /// # Returns
63    ///
64    /// * `Ok(String)` - The fixed JSON string
65    /// * `Err(JsonFixerError)` - If the input is too malformed to be fixed
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use json_fixer::{JsonFixer, JsonFixerConfig};
71    ///
72    /// let input = r#"{
73    ///     c: 3,
74    ///     a: 1,
75    ///     b: 2
76    /// }"#;
77    ///
78    /// let mut config = JsonFixerConfig::default();
79    /// config.sort_keys = true;
80    /// config.beautify = true;
81    ///
82    /// let result = JsonFixer::fix_with_config(input, config).unwrap();
83    /// ```
84    pub fn fix_with_config(input: &str, config: JsonFixerConfig) -> Result<String, JsonFixerError> {
85        let mut parser = JsonParser::new(input, config);
86        parser.parse()
87    }
88    /// Fixes malformed JSON using default configuration.
89    ///
90    /// This method attempts to fix common JSON syntax errors while maintaining
91    /// a compact output format.
92    ///
93    /// # Arguments
94    ///
95    /// * `input` - The JSON string to fix
96    ///
97    /// # Returns
98    ///
99    /// * `Ok(String)` - The fixed JSON string
100    /// * `Err(JsonFixerError)` - If the input is too malformed to be fixed
101    ///
102    /// # Examples
103    ///
104    /// ```
105    /// use json_fixer::JsonFixer;
106    ///
107    /// let input = r#"{ name: 'John', age: 30 hobbies: ['reading' 'coding'] }"#;
108    /// let result = JsonFixer::fix(input).unwrap();
109    /// assert_eq!(result, r#"{"name":"John","age":30,"hobbies":["reading","coding"]}"#);
110    /// ```
111    pub fn fix(input: &str) -> Result<String, JsonFixerError> {
112        let mut parser = JsonParser::new(input, JsonFixerConfig::default());
113        parser.parse()
114    }
115    /// Fixes JSON and adds spaces between keys, values, and punctuation.
116    ///
117    /// This method applies minimal formatting to make the JSON more readable
118    /// while keeping it on a single line.
119    ///
120    /// # Arguments
121    ///
122    /// * `input` - The JSON string to fix
123    ///
124    /// # Returns
125    ///
126    /// * `Ok(String)` - The fixed JSON string with added spacing
127    /// * `Err(JsonFixerError)` - If the input is too malformed to be fixed
128    ///
129    /// # Examples
130    ///
131    /// ```
132    /// use json_fixer::JsonFixer;
133    ///
134    /// let input = r#"{name:"John",age:30}"#;
135    /// let result = JsonFixer::fix_with_space_between(input).unwrap();
136    /// assert_eq!(result, r#"{ "name": "John", "age": 30 }"#);
137    /// ```
138    pub fn fix_with_space_between(input: &str) -> Result<String, JsonFixerError> {
139        let mut config = JsonFixerConfig::default();
140
141        config.space_between = true;
142        config.beautify = false;
143        config.preserve = false;
144        let mut parser = JsonParser::new(input, config);
145        parser.parse()
146    }
147     /// Fixes JSON and applies pretty printing with proper indentation.
148    ///
149    /// This method formats the JSON to be human-readable with proper indentation
150    /// and line breaks.
151    ///
152    /// # Arguments
153    ///
154    /// * `input` - The JSON string to fix
155    ///
156    /// # Returns
157    ///
158    /// * `Ok(String)` - The fixed and formatted JSON string
159    /// * `Err(JsonFixerError)` - If the input is too malformed to be fixed
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use json_fixer::JsonFixer;
165    ///
166    /// let input = r#"{name:"John",age:30,hobbies:["reading","coding"]}"#;
167    /// let result = JsonFixer::fix_pretty(input).unwrap();
168    /// // Result will be:
169    /// // {
170    /// //     "name": "John",
171    /// //     "age": 30,
172    /// //     "hobbies": [
173    /// //         "reading",
174    /// //         "coding"
175    /// //     ]
176    /// // }
177    /// ```
178    pub fn fix_pretty(input: &str) -> Result<String, JsonFixerError> {
179        let mut config = JsonFixerConfig::default();
180        config.beautify = true;
181        config.preserve = false;
182        config.space_between = false;
183
184        let mut parser = JsonParser::new(input, config);
185        parser.parse()
186    }
187}
188
189/*
190************************** Gated behind serde *************************
191*/
192
193
194#[cfg(feature = "serde")]
195impl JsonFixer {
196    /// Converts a Rust type to a JSON string with optional formatting.
197    ///
198    /// This method is only available when the `serde` feature is enabled.
199    ///
200    /// # Type Parameters
201    ///
202    /// * `T` - The type to serialize, must implement `serde::Serialize`
203    ///
204    /// # Arguments
205    ///
206    /// * `value` - The value to convert to JSON
207    /// * `config` - Optional configuration for JSON formatting
208    ///
209    /// # Returns
210    ///
211    /// * `Ok(String)` - The JSON string representation
212    /// * `Err(JsonFixerError)` - If serialization fails
213    ///
214    /// # Examples
215    ///
216    /// ```
217    /// use json_fixer::JsonFixer;
218    /// use serde::Serialize;
219    ///
220    /// #[derive(Serialize)]
221    /// struct Person {
222    ///     name: String,
223    ///     age: u32,
224    /// }
225    ///
226    /// let person = Person {
227    ///     name: "John".to_string(),
228    ///     age: 30,
229    /// };
230    ///
231    /// let json = JsonFixer::to_json(&person, None).unwrap();
232    /// ```
233    pub fn to_json<T: serde::Serialize>(
234        value: &T,
235        config: Option<JsonFixerConfig>,
236    ) -> Result<String, JsonFixerError> {
237        let serde_output =
238            serde_json::to_string(value).map_err(|e| JsonFixerError::SerdeError(e.to_string()))?;
239
240        let mut parser = JsonParser::new(&serde_output, config.unwrap_or_default());
241        parser.parse()
242    }
243
244    /// Parses a JSON string into a Rust type without fixing.
245    ///
246    /// This method is only available when the `serde` feature is enabled.
247    ///
248    /// # Type Parameters
249    ///
250    /// * `T` - The type to deserialize into, must implement `serde::Deserialize`
251    ///
252    /// # Arguments
253    ///
254    /// * `input` - The JSON string to parse
255    ///
256    /// # Returns
257    ///
258    /// * `Ok(T)` - The deserialized value
259    /// * `Err(JsonFixerError)` - If parsing fails
260    ///
261    /// # Examples
262    ///
263    /// ```
264    /// use json_fixer::JsonFixer;
265    /// use serde::Deserialize;
266    ///
267    /// #[derive(Deserialize)]
268    /// struct Person {
269    ///     name: String,
270    ///     age: u32,
271    /// }
272    ///
273    /// let json = r#"{"name":"John","age":30}"#;
274    /// let person: Person = JsonFixer::from_str(json).unwrap();
275    /// ```
276    pub fn from_str<T: for<'de> serde::Deserialize<'de>>(input: &str) -> Result<T, JsonFixerError> {
277        serde_json::from_str::<T>(input).map_err(|e| JsonFixerError::SerdeError(e.to_string()))
278    }
279
280    /// Fixes malformed JSON and then parses it into a Rust type.
281    ///
282    /// This method is only available when the `serde` feature is enabled.
283    ///
284    /// # Type Parameters
285    ///
286    /// * `T` - The type to deserialize into, must implement `serde::Deserialize`
287    ///
288    /// # Arguments
289    ///
290    /// * `input` - The potentially malformed JSON string to fix and parse
291    /// * `config` - Optional configuration for JSON fixing
292    ///
293    /// # Returns
294    ///
295    /// * `Ok(T)` - The deserialized value
296    /// * `Err(JsonFixerError)` - If fixing or parsing fails
297    ///
298    /// # Examples
299    ///
300    /// ```
301    /// use json_fixer::JsonFixer;
302    /// use serde::Deserialize;
303    ///
304    /// #[derive(Deserialize)]
305    /// struct Person {
306    ///     name: String,
307    ///     age: u32,
308    /// }
309    ///
310    /// let json = r#"{ name: "John", age: 30 }"#;  // Note: unquoted keys
311    /// let person: Person = JsonFixer::from_fixed(json, None).unwrap();
312    /// ```
313    pub fn from_fixed<T: for<'de> serde::Deserialize<'de>>(
314        input: &str,
315        config: Option<JsonFixerConfig>,
316    ) -> Result<T, JsonFixerError> {
317        let mut parser = JsonParser::new(input, config.unwrap_or_default());
318        let fixed = parser.parse()?;
319        serde_json::from_str(&fixed).map_err(|e| JsonFixerError::SerdeError(e.to_string()))
320    }
321}