source-lang 1.0.0

Source file and buffer management with multi-file source maps.
Documentation
# source-lang v1.0.0 — stable

**1.0.** The public API is frozen and stable. v0.2.0 built the core source map,
v0.3.0 made it loadable and diagnostic-ready, v0.4.0 added serialization and froze
the surface. This release ratifies that surface as the `1.0` contract: it follows
Semantic Versioning, carries no breaking changes before `2.0`, and ships with the
full property-test and benchmark suite verified on Linux, macOS, and Windows.

There is no new public API in `1.0.0` — by design. A `0.4.0` program compiles and
behaves identically against `1.0.0`.

## What is source-lang?

The multi-file coordinate layer of a compiler front-end. It loads files and
in-memory buffers, gives each a stable `SourceId`, lays them out in one global
position space, and maps any global position back to the source and local offset —
or the file, line, and column — it came from. It is the layer above `span-lang`: a
`Span` says *where in a buffer* an error is, source-lang says *which buffer*. It owns
source storage and coordinate mapping only.

```rust
use source_lang::{BytePos, SourceMap};

let mut map = SourceMap::new();
map.add("main.rs", "fn main() {}")?;                  // global 0..12
let util = map.add("util.rs", "fn helper() {}")?;     // global 12..26

let (id, local) = map.locate(BytePos::new(13)).expect("inside util.rs");
assert_eq!(id, util);
assert_eq!(local, BytePos::new(1)); // 13 - 12
# Ok::<(), source_lang::SourceMapError>(())
```

## The 1.0 surface

The frozen contract is the complete source map:

- **Construction**`SourceMap::new`, `with_capacity`, `Default`.
- **Loading**, all through one validated insertion path — `add` (text), `add_bytes`
  (raw bytes, UTF-8 checked), `add_file` (disk, `std` feature), with the
  `set_max_source_len` / `max_source_len` size ceiling.
- **Resolution**`locate` (global → source + local offset, `O(log files)`),
  `line_col` (global → source + 1-based line/column), `source`, `iter`, `len`,
  `is_empty`.
- **Types**`SourceFile` (with `line_index`), `SourceId`, the `#[non_exhaustive]`
  `SourceMapError`, and the re-exported `span-lang` coordinate types `BytePos`,
  `Span`, `LineCol`, `LineIndex`.
- **Serialization**`serde` for `SourceMap` and `SourceId` under the `serde`
  feature, with a stable wire format.

## SemVer promise

The crate follows [Semantic Versioning](https://semver.org):

- No documented item is removed or changed in a breaking way within `1.x`; breaking
  changes wait for `2.0`.
- New functionality is additive and arrives in minor releases. `SourceMapError` is
  `#[non_exhaustive]`, so a new error variant is a minor change.
- The MSRV is Rust `1.85`; raising it is a minor change, never a patch.
- The `serde` wire format is part of the contract — a map written by one `1.x` reads
  back in any later `1.x`.

The full statement lives in [`docs/API.md`](https://github.com/jamesgober/source-lang/blob/main/docs/API.md#semver-promise).

## Breaking changes

**None.** `1.0.0` is API-identical to `0.4.0`.

## Verification

Run on Windows x86_64 and Linux x86_64 (WSL2 Ubuntu), Rust stable and 1.85 MSRV; the
same commands run across the CI matrix on Linux, macOS, and Windows:

```bash
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo test --all-features
cargo build --no-default-features
cargo +1.85 build --all-features
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
cargo audit
cargo deny check
```

All green. Counts at this tag:

- `--all-features`: 27 unit + 6 file-loading + 5 property + 5 serde + 23 doctests.
- Default features: identical minus the serde integration tests.

The four section-4 invariants — unique/stable ids, non-overlapping ranges, the
global ↔ (id, local) round-trip, and `line_col` against per-file resolution — are
held to a naive linear-scan oracle across a wide `proptest` input space. The
`locate` and `line_col` hot paths carry `criterion` benchmarks: `locate` is roughly
4 ns per lookup at 16 sources and 40 ns at 65,536, the shape of `O(log files)`.

## What's next

The `1.0` surface is stable until `2.0`. Future work is documentation, tests, and
internal optimisation that does not change the public contract.

## Installation

```toml
[dependencies]
source-lang = "1.0"
```

With serialization:

```toml
[dependencies]
source-lang = { version = "1.0", features = ["serde"] }
```

MSRV: Rust 1.85.

## Documentation

- [README]https://github.com/jamesgober/source-lang/blob/main/README.md
- [API Reference]https://github.com/jamesgober/source-lang/blob/main/docs/API.md
- [CHANGELOG]https://github.com/jamesgober/source-lang/blob/main/CHANGELOG.md

---

**Full diff:** [`v0.4.0...v1.0.0`](https://github.com/jamesgober/source-lang/compare/v0.4.0...v1.0.0).
**Changelog:** [`CHANGELOG.md`](https://github.com/jamesgober/source-lang/blob/main/CHANGELOG.md#100---2026-06-20).