Skip to main content

sluice/
lib.rs

1//! Pure-Rust streaming parser for the
2//! [Maven Central Nexus binary index format](https://maven.apache.org/repository/central-index.html).
3//!
4//! The crate is I/O-neutral: it operates on any [`std::io::Read`] and has no
5//! knowledge of gzip, files, HTTP, or JSON. Gzip wrapping and output belong
6//! to the CLI crate. For a byte-level specification see
7//! [`docs/binary-format.md`](https://github.com/overengineered-dev/sluice/blob/main/docs/binary-format.md).
8//!
9//! # Quick start
10//!
11//! ```
12//! use std::io::Cursor;
13//! use sluice::{IndexReader, Record};
14//!
15//! // A minimal binary stream: version 0x01, timestamp, then one artifact-add document.
16//! let mut stream = Vec::new();
17//! stream.push(0x01u8);                                       // version
18//! stream.extend_from_slice(&1_700_000_000_000i64.to_be_bytes()); // timestamp
19//! stream.extend_from_slice(&3i32.to_be_bytes());             // field count
20//! // field: flags=0x05, name="u", value="org.example|mylib|1.0|NA|jar"
21//! stream.push(0x05);
22//! stream.extend_from_slice(&1u16.to_be_bytes());
23//! stream.extend_from_slice(b"u");
24//! let uinfo = b"org.example|mylib|1.0|NA|jar";
25//! stream.extend_from_slice(&(uinfo.len() as i32).to_be_bytes());
26//! stream.extend_from_slice(uinfo);
27//! // field: flags=0x04, name="i", value="jar|1700000000000|123|0|0|0|jar"
28//! stream.push(0x04);
29//! stream.extend_from_slice(&1u16.to_be_bytes());
30//! stream.extend_from_slice(b"i");
31//! let info = b"jar|1700000000000|123|0|0|0|jar";
32//! stream.extend_from_slice(&(info.len() as i32).to_be_bytes());
33//! stream.extend_from_slice(info);
34//! // field: flags=0x04, name="m", value="1700000000000"
35//! stream.push(0x04);
36//! stream.extend_from_slice(&1u16.to_be_bytes());
37//! stream.extend_from_slice(b"m");
38//! let modified = b"1700000000000";
39//! stream.extend_from_slice(&(modified.len() as i32).to_be_bytes());
40//! stream.extend_from_slice(modified);
41//!
42//! let reader = IndexReader::new(Cursor::new(stream))?;
43//! assert_eq!(reader.header().version, 0x01);
44//!
45//! for doc in reader {
46//!     let doc = doc?;
47//!     match Record::try_from(&doc)? {
48//!         Record::ArtifactAdd(u) => {
49//!             assert_eq!(u.group_id, "org.example");
50//!             assert_eq!(u.artifact_id, "mylib");
51//!         }
52//!         _ => {}
53//!     }
54//! }
55//! # Ok::<(), sluice::ParseError>(())
56//! ```
57
58#![warn(missing_docs)]
59
60pub mod domain;
61/// Error type for parsing operations.
62pub mod error;
63/// Streaming parser over a binary index stream.
64pub mod parser;
65
66pub use domain::{
67    document::Document, field::Field, flags::FieldFlags, header::IndexHeader, record::Record,
68    uinfo::Uinfo,
69};
70pub use error::ParseError;
71pub use parser::IndexReader;