libxml_rs/lib.rs
1//! libxml-rs: Custodial native-Rust reimplementation of libxml2 and libxslt
2//!
3//! This is not an XML crate. This is not an XSLT crate. This is not a wrapper.
4//! This is a forensic reconstruction of the observable behavior of the libxml2 + libxslt
5//! ecosystem across its historical lifetime, implemented in native Rust.
6//!
7//! # Architecture
8//!
9//! The crate is organized into semantic modules corresponding to real ownership boundaries:
10//!
11//! - `abi` - C ABI compatibility layer: types, structs, constants, exports, callbacks, allocator, ownership, versioning
12//! - `xml` - libxml2 implementation: parser, SAX, tree, entities, namespaces, DTD, validation, reader, writer, encoding, I/O, catalog, URI, XPath, XPointer, XInclude, RELAX NG, schemas, Schematron, C14N, HTML, regex, automata, dictionary, hash, list, debug, globals, threads, errors, memory
13//! - `xslt` - libxslt implementation: stylesheet, compiler, transform, templates, patterns, variables, parameters, keys, attributes, namespace_alias, whitespace, sorting, numbering, documents, imports, extensions, serialization, security, errors
14//! - `exslt` - EXSLT modules: common, math, sets, strings, dynamic, functions, dates
15//! - `compatibility` - Historical profiles, quirks, platform-specific behavior
16//! - `bin` - CLI tools: xmllint, xmlcatalog, xsltproc
17//!
18//! # Safety
19//!
20//! This crate uses `unsafe` only where fundamentally required for C ABI export, raw-pointer
21//! compatibility, foreign allocator interoperability, public C structure layout, callbacks,
22//! variadic compatibility, OS interfaces, and dynamic-loader interaction.
23//!
24//! Every unsafe block documents:
25//! - What must be true
26//! - Who establishes it
27//! - How long it remains true
28//! - Which oracle/parity court exercises the assumption
29//! - What would constitute violation
30
31#![deny(unconditional_recursion, unused_lifetimes, while_true)]
32// Lint policy, sealed at 11.1-Z. This crate is a C-ABI mirror of
33// libxml2/libxslt; the hot lint surface is raw-pointer plumbing and
34// C-signal integer casts that are *deliberate* parity decisions (e.g.
35// `i32` -> `usize` mirrors what upstream C does; rewriting cast_sign_loss
36// sites with `try_from().unwrap()` would introduce panics that do not
37// exist in the oracle). Consequently:
38//
39// - `clippy::all` plus the rustc doc lints is the enforced gate and is
40// kept clean: `cargo clippy --all-targets --all-features -- -D warnings`
41// passes at the 11.1-Z seal (every remaining unsafe fn carries a
42// `# Safety` section; missing_docs is allowed only on the C-header
43// mirror modules structs.rs/types.rs, where the C headers are the
44// canonical documentation, matching bindgen's default).
45// - `clippy::pedantic`/`clippy::nursery` are NOT gated. clippy documents
46// pedantic as "opinionated" and nursery as "experimental"; their two
47// largest families here (ptr_as_ptr ~4.5k and cast_* ~1.6k instances
48// in the lib) are inherent to the ABI-mirror domain, so enforcing them
49// would force either semantically-worse code or thousands of per-site
50// `#[allow]` attributes. They were enabled-but-dirty since crate
51// inception; the seal converts the policy to what is actually enforced.
52// - `clippy::missing_inline_in_public_items` is not gated: the
53// `#[no_mangle] extern "C"` export surface cannot be inlined across
54// the FFI boundary, making the lint noise on ~500 exports.
55#![warn(
56 missing_docs,
57 missing_debug_implementations,
58 clippy::all,
59 clippy::cargo,
60 clippy::missing_const_for_fn
61)]
62#![allow(
63 // The C-API ports declare every out-parameter with a NULL/0 initializer
64 // mirroring upstream C (`xmlXPathObjectPtr obj = NULL;`); Rust flags the
65 // dead initializer as unused_assignments, which is deliberate parity
66 // structure (it keeps the port textually aligned with upstream for
67 // archaeology/diff review), not a bug.
68 unused_assignments,
69 clippy::module_name_repetitions,
70 clippy::multiple_crate_versions,
71 clippy::too_many_lines,
72 clippy::type_complexity,
73 // C ABI type names must mirror the upstream headers verbatim; the
74 // `xml...` acronym spellings are the exported API, so renames that
75 // clippy suggests would break the ABI/API mirror. Likewise the
76 // non_snake_case locals/parameters mirror upstream C variable names
77 // (e.g. `pubID`, `SystemID`, `mallocFunc`) to keep the ports textually
78 // aligned with the archaeology source for diff review.
79 clippy::upper_case_acronyms,
80 non_camel_case_types,
81 non_snake_case,
82 // The internal safe wrapper API (dictionary/list/hash/tree/errors
83 // helpers) null-checks raw pointers before dereferencing them,
84 // mirroring upstream's NULL-tolerant C functions; the wrappers are the
85 // crate's safe facade, and marking them `unsafe` would push unsafe
86 // blocks into every caller. The C ABI exports that deref are declared
87 // `unsafe extern "C"` and carry `# Safety` sections.
88 clippy::not_unsafe_ptr_arg_deref,
89)]
90
91// Public ABI compatibility layer
92pub mod abi;
93
94// libxml2 implementation
95pub mod xml;
96
97// libxslt implementation
98pub mod xslt;
99
100// EXSLT implementation
101pub mod exslt;
102
103// Compatibility profiles and historical behavior
104pub mod compatibility;
105
106// Binary entry points are defined as [[bin]] targets in Cargo.toml.
107// They are NOT library modules — they depend on libxml_rs as a library.
108// See src/bin/xmllint.rs, src/bin/xmlcatalog.rs, src/bin/xsltproc.rs
109
110// Phase 0: ABI re-exports will be populated when types are defined.
111// The `allow(unused_imports)` is intentional — these will be used in Phase 1+.
112#[allow(unused_imports)]
113use abi::allocator::*;
114#[allow(unused_imports)]
115use abi::callbacks::*;
116#[allow(unused_imports)]
117use abi::constants::*;
118#[allow(unused_imports)]
119use abi::ownership::*;
120#[allow(unused_imports)]
121use abi::structs::*;
122#[allow(unused_imports)]
123use abi::types::*;
124#[allow(unused_imports)]
125use abi::versioning::*;
126
127// Internal modules (not part of public C ABI)
128mod internal;
129
130// Property-based fuzzing smoke targets (proptest, runs in `cargo test`).
131#[cfg(test)]
132mod fuzz;
133
134/// The full version string of the libxml-rs crate (from Cargo.toml).
135pub const LIBXML_RS_VERSION: &str = env!("CARGO_PKG_VERSION");
136
137/// Major version number of libxml-rs.
138pub const LIBXML_RS_VERSION_MAJOR: u32 = 0;
139
140/// Minor version number of libxml-rs.
141pub const LIBXML_RS_VERSION_MINOR: u32 = 1;
142
143/// Micro version (patch) number of libxml-rs.
144pub const LIBXML_RS_VERSION_MICRO: u32 = 0;