Skip to main content

qubit_json/
lib.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8//! Provides the public API for the `qubit-json` crate.
9//!
10//! The crate exposes a lenient JSON decoder and the related option and error
11//! types needed to normalize and deserialize JSON text from
12//! non-fully-trusted sources.
13//!
14//! # Quick start
15//!
16//! ```rust
17//! use qubit_json::{JsonDecodeOptions, LenientJsonDecoder};
18//!
19//! let decoder = LenientJsonDecoder::new(
20//!     JsonDecodeOptions::default().with_max_input_bytes(Some(1024)),
21//! );
22//! let value = decoder.decode_value("```json\n{\"ok\":true}\n```")?;
23//!
24//! assert_eq!(value["ok"], true);
25//! # Ok::<(), qubit_json::JsonDecodeError>(())
26//! ```
27//!
28//! # Error privacy
29//!
30//! Errors are redacted by default: input-derived serde messages and values are
31//! excluded from the message, debug representation, and standard error source.
32//! Safe structural metadata, including parser locations and UTF-8 failure
33//! offsets, remains available. Detailed diagnostics must be enabled explicitly
34//! and may expose input values.
35//!
36//! ```rust
37//! use qubit_json::{
38//!     ErrorPrivacyPolicy,
39//!     JsonDecodeOptions,
40//!     LenientJsonDecoder,
41//! };
42//!
43//! let redacted = LenientJsonDecoder::default()
44//!     .decode::<u64>(r#""TOP_SECRET""#)
45//!     .expect_err("a JSON string cannot deserialize into u64");
46//! assert_eq!(redacted.privacy_policy(), ErrorPrivacyPolicy::Redacted);
47//! assert!(!redacted.to_string().contains("TOP_SECRET"));
48//! assert!(std::error::Error::source(&redacted).is_none());
49//!
50//! let detailed = LenientJsonDecoder::new(
51//!     JsonDecodeOptions::default()
52//!         .with_error_privacy_policy(ErrorPrivacyPolicy::Detailed),
53//! )
54//! .decode::<u64>(r#""TOP_SECRET""#)
55//! .expect_err("a JSON string cannot deserialize into u64");
56//! assert_eq!(detailed.privacy_policy(), ErrorPrivacyPolicy::Detailed);
57//! assert!(std::error::Error::source(&detailed).is_some());
58//! ```
59//!
60//! # Must-use configuration values
61//!
62//! ```compile_fail
63//! #![deny(unused_must_use)]
64//! qubit_json::JsonDecodeOptions::default();
65//! ```
66//!
67//! ```compile_fail
68//! #![deny(unused_must_use)]
69//! qubit_json::LenientJsonDecoder::default();
70//! ```
71
72#![deny(missing_docs)]
73
74mod error;
75mod internal;
76mod json_top_level_kind;
77mod lenient_json_decoder;
78mod options;
79
80pub use error::{
81    ErrorPrivacyPolicy,
82    JsonDecodeError,
83    JsonDecodeErrorKind,
84    JsonDecodeStage,
85};
86pub use json_top_level_kind::JsonTopLevelKind;
87pub use lenient_json_decoder::LenientJsonDecoder;
88pub use options::{
89    JsonDecodeOptions,
90    MarkdownFenceClosing,
91    MarkdownFencePolicy,
92};