osproxy_rewrite/lib.rs
1//! Body and query transforms.
2//!
3//! Pure transforms with no network or placement lookup: scalar extraction from
4//! a document body, document-`_id` construction, and tenancy-field
5//! inject/strip. Held to the highest coverage bar including branch coverage
6//! (`docs/09`).
7//!
8//! This crate deliberately depends only on [`osproxy_core`] and `serde_json`:
9//! it speaks in primitives (paths, names, JSON values), and the tenancy adapter
10//! (`osproxy-tenancy`) translates SPI rule types into these calls. That keeps
11//! the transforms a small, exhaustively testable leaf of the dependency graph.
12//!
13//! M2 adds query-DSL filter wrapping ([`wrap_query`], `docs/04` §4) and the
14//! logical↔physical id mapping for by-id reads. Bulk NDJSON demux (`docs/04`
15//! §3) lands in M3 alongside its endpoint.
16#![deny(missing_docs)]
17
18mod bulk;
19mod error;
20mod extract;
21mod fields;
22mod id;
23mod mget;
24mod msearch;
25mod query;
26
27pub use bulk::{parse_bulk, parse_bulk_action, parse_bulk_op, BulkAction, BulkItem};
28pub use error::RewriteError;
29pub use extract::extract_scalar;
30pub use fields::{inject_fields, inject_fields_bytes, inject_update, strip_fields};
31pub use id::{construct_id, construct_id_bytes, map_logical_to_physical, map_physical_to_logical};
32pub use mget::{parse_mget, MgetItem};
33pub use msearch::{parse_msearch, MsearchItem};
34pub use query::wrap_query;
35
36/// Validates that `body` is a single well-formed JSON document, allocating
37/// nothing, for the verbatim write path, which forwards the body unchanged but
38/// must still reject malformed input.
39///
40/// # Errors
41///
42/// [`RewriteError::InvalidJson`] if `body` is not valid JSON.
43pub fn validate_json(body: &[u8]) -> Result<(), RewriteError> {
44 osproxy_core::json::validate(body).map_err(RewriteError::from)
45}