Skip to main content

Crate laterite

Crate laterite 

Source
Expand description

Read, validate, repair and write AGS4 — the geotechnical data transfer format.

use laterite::ags4;

// Read
let mut doc = ags4::read("delivery.ags").run()?;
for group in doc.groups() {
    println!("{} — {} rows", group.code(), group.len());
}

// Validate — from a path...
let report = ags4::validate("delivery.ags").warnings(true).run()?;
for finding in report.findings() {
    println!("{}: {}", finding.rule(), finding.description());
}

// ...or from bytes that never touch a filesystem, for a service that
// validates an upload without giving it a disk to sit on.
let upload: &[u8] = b"\"GROUP\",\"PROJ\"\r\n";
let report = ags4::validate_bytes(upload).run()?;

// Modify and write
doc.set_cell("PROJ", 0, "PROJ_NAME", "Renamed site")?;
ags4::write(&doc).to_path("out.ags")?;

// Repair a delivery mechanically — the result carries what could NOT be
// fixed, and the source file is untouched until you name a destination.
let fixed = ags4::fix("delivery.ags").run()?;
println!("{} repaired, {} left", fixed.fixes_applied(), fixed.findings().len());

// Or construct AGS4 from data you hold rather than a file you read.
use laterite::ags4::GroupData;
let proj = GroupData::new("PROJ", ["PROJ_ID", "PROJ_NAME"]).row(["P1", "A site"]);
let built = ags4::build(vec![proj]).run()?;

§What this crate promises

It is a facade. The work happens in a tier of laterite-ags4-* engine crates, which move on their own version and reshape as the format work demands. This crate exists so that their reshaping does not reach you — a promise about the engine, kept by the rules below.

Concretely, and these are the rules the API is built to:

  • Everything AGS4-specific lives under ags4. The crate root stays format-neutral. AGS4 is not the last version of the format, and a root-level laterite::read would have to mean one of them forever. transport is at the root because it genuinely is format-neutral — zstd and age over any bytes.
  • Handles are opaque. ags4::Document, ags4::Report and the rest have private fields. You reach data through methods, so the engine’s own structs can change shape without editing your code.
  • No third-party type appears in a public signature. Not serde_json::Value, not chrono, not encoding_rs, not arrow. Encodings are WHATWG label strings, dates are ISO strings. This is the highest-leverage rule here: no dependency’s major version can ever force one of ours.
  • One Error with a coarse, #[non_exhaustive] ErrorKind and a stable Error::kind_str shared with the Python, Node and lat surfaces.

The crate is at parity with the Python and Node surfaces — per capability, at least what the weaker of those two offers — and carries the product version: cargo add laterite and pip install laterite name the same release. While the product line is pre-1.0 a breaking change takes the minor, and Cargo will not carry you across a 0.x minor on the caret requirement cargo add writes, so an upgrade is yours to take rather than something that happens to you.

What that means for every surface is stated once, at https://docs.laterite.dev/reference/support/.

The unstable-engine feature is the only way past the facade. It is a feature rather than a hidden module because it shows up in your Cargo.toml — reaching past a stability boundary should be something you wrote down.

§Scope

Read, validate, fix, build, write, certify, diff, merge, transport (compress / encrypt any file), and — behind the optional excel feature — XLSX conversion in both directions.

Parity was reached once, then the crate left 0.1.x for the product line in a single jump — there was never a 0.2, deliberately: a waypoint version would have existed for as long as the remaining work took, on a crate whose purpose is to be a stable surface over a moving engine.

Modules§

ags4
The AGS4 surface: read, validate, fix, build, write, diff, merge — and, behind the excel feature, XLSX conversion in both directions.
transport
Compress and encrypt any file — zstd, and zstd + an age passphrase.

Structs§

Error
An error from any laterite operation.

Enums§

ErrorKind
What went wrong, coarsely.