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}